矩形覆蓋求並 二維離散化 掃瞄線演算法

2021-08-09 02:21:24 字數 1524 閱讀 1302

problem:

給了n個矩形的左下角座標和右上角座標,求這n個矩形的面積和,覆蓋部分只計算一次。

2017廣西南寧acm區域賽:

solution:

利用掃瞄線演算法進行離散化,然後再求和。

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

double x[2002],y[2002];//最多100個矩形,所以最多只有200條橫線或縱線

double a[1002][4];//矩形實際座標

bool cover[2002][2002];

const

double eps = 1e-7;

int cmp(const

void * b,const

void * a)

int main()

for(i=0,k=0;iscanf("%lf%lf%lf%lf",&a[i][0],&a[i][1],&a[i][2],&a[i][3]);

x[k]=a[i][0],y[k]=a[i][1],x[++k]=a[i][2],y[k]=a[i][3];

}qsort(x,2*n,sizeof(x[0]),cmp);

qsort(y,2*n,sizeof(y[0]),cmp);//將橫線,豎線排好序

memset(cover,0,sizeof(cover));//初始時無覆蓋區

//對每個矩形,進行一次橫縱線的掃瞄,覆蓋範圍

for(i=0;i0;

while(fabs(x[k]-a[i][0])>eps)k++;h1=k;

k=0;

while(fabs(y[k]-a[i][1])>eps)k++;v1=k;

k=0;

while(fabs(x[k]-a[i][2])>eps)k++;h2=k;

k=0;

while(fabs(y[k]-a[i][3])>eps)k++;v2=k;

//標記該矩形覆蓋的區域

for(j=h1;j//不考慮最右

for(k=v1;k//不考慮最下

cover[j][k]=true;

}double sum=0;

//計算總面積

for(i=0;i<2*n-1;i++)

for(j=0;j<2*n-1;j++)

sum+=(cover[i][j]*(x[i+1]-x[i])*(y[j+1]-y[j]));

printf("%d\n", (int)round(sum));

}}

線段樹求矩形面積並 掃瞄線 離散化

顧名思義,掃瞄法就是用一根想象中的線掃過所有矩形,在寫 的過程中,這根線很重要。方向的話,可以左右掃,也可以上下掃。方法是一樣的,這裡我用的是由下向上的掃瞄法。如上圖所示,座標系內有兩個矩形。位置分別由左下角和右上角頂點的座標來給出。上下掃瞄法是對x軸建立線段樹,矩形與y平行的兩條邊是沒有用的,在這...

線段樹求矩形面積並 掃瞄線 離散化

顧名思義,掃瞄法就是用一根想象中的線掃過所有矩形,在寫 的過程中,這根線很重要。方向的話,可以左右掃,也可以上下掃。方法是一樣的,這裡我用的是由下向上的掃瞄法。如上圖所示,座標系內有兩個矩形。位置分別由左下角和右上角頂點的座標來給出。上下掃瞄法是對x軸建立線段樹,矩形與y平行的兩條邊是沒有用的,在這...

二維座標離散化

離散化的思想就是將分布大卻數量少 即稀疏 的資料進行集中化的處理,這樣可以有利於程式的空間與時間,能減少遍歷次數與空間儲存。然而雖然我會了思想今天問了翔神半天才知道怎麼實現。其實實現的方式與口述的角度還是有所不同。思想理解起來其實道理很簡單,如座標 3,2000 10005,31 10006,5 離...