1. 程式人生 > 實用技巧 >Urban Elevations UVA - 221

Urban Elevations UVA - 221

基本是參考劉老師的思路和其他大佬的程式碼寫的,這道題完全不會

原題連結

思路:兩個x座標形成的區間要麼完全可見要麼完全不可見,如果有建築可見,那麼它一定在x的區間裡,因此每個建築遍歷x區間即可

之前看了一半提示的思路是隻列舉建組起點形成的區間,但這樣能舉出反例:只有兩個平行建築此思路就錯誤

將x座標儲存,但要記得排序與去重(其實就是離散化)

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 vector<int> alls,ans;
 4 int n;
 5 struct city{//利用區間端點的性質 
 6     int
id; 7 double x,y,width,len,h; 8 bool operator<(city p){ 9 if(this->x==p.x) return this->y<p.y; 10 return this->x<p.x; 11 } 12 }cities[120]; 13 bool Isvis(double mid,int i) 14 { 15 if(cities[i].x>mid||cities[i].x+cities[i].width<mid) return false
; 16 for(int j=1;j<=n;j++){ 17 if(j!=i&&cities[j].x+cities[j].width>=mid&&cities[j].x<=mid&&cities[j].y<=cities[i].y&&cities[j].h>=cities[i].h) 18 return false; 19 } 20 return true; 21 } 22 int main() 23 { 24 int kcase = 0
; 25 while(scanf("%d",&n)&&n) 26 { 27 alls.clear();ans.clear(); 28 29 if(kcase) printf("\n"); 30 printf("For map #%d, the visible buildings are numbered as follows:\n",++kcase); 31 for(int i=1;i<=n;i++){ 32 cities[i].id = i; 33 cin>>cities[i].x>>cities[i].y>>cities[i].width>>cities[i].len>>cities[i].h; 34 alls.push_back(cities[i].x); alls.push_back(cities[i].x+cities[i].width);//需要離散化的座標 35 } 36 sort(cities+1,cities+n+1); 37 sort(alls.begin(),alls.end()); 38 alls.erase(unique(alls.begin(),alls.end()),alls.end()); 39 for(int i=1;i<=n;i++){ 40 for(int j=0;j<alls.size()-1;j++){ 41 double mid = (alls[j]+alls[j+1])/2; 42 if(Isvis(mid,i)) {ans.push_back(cities[i].id);break;}//只要在一個區間能看見 43 } 44 } 45 for(int p=0;p<ans.size();p++){ 46 if(p) printf(" %d",ans[p]); 47 else printf("%d",ans[p]); 48 } 49 printf("\n"); 50 } 51 }