UVa 221 Urban Elevations 城市正視圖 離散化初步 無限化有限
阿新 • • 發佈:2017-08-07
nat www 順序 main 高端 any tro record last
轉載請註明:
仰望高端玩家的小清新 http://www.cnblogs.com/luruiyuan/
題目大意:
題目傳送門:UVa 221 Urban Elevations
給出城市中建築物的x, y 坐標的最小值:x,y , 再給出其以左下角為坐標原點的關於x軸、y軸上的長度 w, 和 d,最後給出建築物的高度 h,將建築物的正視圖中,能夠看到的建築物的id打印出來:要求先打印x小的,當x相同時,打印y小的。為了簡化,假定建築物都是長方體。同時,每個輸出之間要用一個空行隔開 One blank line must separate output from consecutive input records. (一開始沒註意審題,wa在這了┭┮﹏┭┮)
思路:
首先,這個題我本來沒什麽思路,還是不得不參考一波劉汝佳老師的思路
本題最大的收獲是初步認識了 “離散化” :將無限轉化為有限的方法。
- 首先,我們註意到,每個建築物的深度在這裏沒有影響,因此深度是個幹擾項
- 一個關鍵點是,題目給定的數據是實數,即浮點數,因此我們不能窮舉所有的x坐標來遍歷,對於無窮問題,我們需要考慮離散化,化無窮為有限
- 對於本題,離散化的關鍵在於,如何表示建築物之間的互相重疊的關系
- 必須註意到,每個建築物有2個x坐標,一個是input中直接給出的x,而另一個是我們可以通過w+x得到的“右邊的x坐標”
- 通過2個坐標,我們可以首先對x去重,然後構建出相應的x軸的多個區間,這樣,每一組重疊關系必然會落在我們的x區間之中
- 我們只需在區間內任選一點,即可作為區間的整體代表元素,來判斷某個建築是否經過了此區間,因此,可以選擇比較方便的區間中點。沒有經過區間代表元素的,顯然不會經過該區間。經過了第5步和這一步,我們就將一個無限問題,轉化為有限問題了。
- 對於每個建築,我們考慮2點:是否經過了區間中點;是否存在y坐標小於它,且高度大於等於它的建築。上述兩點滿足任何一點,則該建築都不可見
- 其他小細節:代碼 53 行的 b[j].y < b[i].y 能夠保證 i != j; 53行的判定語句的順序也可以些微提高代碼效率,比如將函數調用延遲到最後一個,以降低調用概率,降低平均運行時間
代碼如下:
1 // UVa 221 Urban Elevations 2 // Ruiyuan Lu 3 #include<cstdio> 4 #include<algorithm> 5 using namespace std; 6 7 const int maxn = 100 + 5; 8 double x[maxn*2]; // each building has 2 coordinates of x axis 9 int n; // number of the buildings 10 11 struct Building{ 12 int id; 13 double x, y, w, d, h; // w: means x_len, d:depth means y_len, h:height 14 bool operator < (const Building& b) const { // sort for output 15 return x < b.x || (x == b.x && y < b.y); 16 } 17 }b[maxn]; 18 19 bool cover(int i, double mx); // determine if the mx is in the range of building‘s x coordinate 20 bool visible(int i, double mx); // i: the index of buildings; mx: middle x coordinate of an interval 21 22 int main(){ 23 int cnt = 0; 24 while(scanf("%d", &n) == 1 && n > 0){ 25 for(int i=0; i<n;i++){ 26 scanf("%lf%lf%lf%lf%lf", &b[i].x, &b[i].y, &b[i].w, &b[i].d, &b[i].h); 27 b[i].id = i + 1; 28 x[i*2] = b[i].x; x[i*2+1] = b[i].x + b[i].w; // init x for discretization 29 } 30 sort(x, x+n*2); // sort before unique() is invoked 31 sort(b, b+n); // sort for output 32 int m = unique(x, x+maxn*2) - x; // get the number of unique x in the array 33 // print result 34 if(cnt++)printf("\n"); // print the ‘\n‘ for last output 35 printf("For map #%d, the visible buildings are numbered as follows:\n%d", cnt, b[0].id); 36 for(int i=1;i<n;i++) 37 for(int j=1;j<m;j++) // check each building if it is visible in any interval of m intervals 38 if(visible(i, (x[j-1] + x[j]) / 2)){ 39 printf(" %d", b[i].id); 40 break; 41 } 42 printf("\n"); // as they required: One blank line must separate output from consecutive input records. 43 } 44 } 45 46 bool cover(int i, double mx){ 47 return b[i].x <= mx && b[i].x + b[i].w >= mx; 48 } 49 50 bool visible(int i, double mx){ 51 if(!cover(i, mx)) return false; 52 for(int j=0;j<n;j++) 53 if(b[j].y < b[i].y && b[j].h >= b[i].h && cover(j, mx)) return false; 54 return true; 55 }
啦啦啦,今天就到這裏啦~改天見*★,°*:.☆( ̄▽ ̄)/$:*.°★* 。
UVa 221 Urban Elevations 城市正視圖 離散化初步 無限化有限