uva 221

来源:互联网 发布:socket文件传输java 编辑:程序博客网 时间:2024/05/17 08:52

方法非常经典的题, 这道是建筑物遮挡, 类似于任务安排类的问题

坐标是实数, 有无穷多个无法枚举的, 就采用将其离散化的思路

具体方法:把所有建筑的横坐标(包括起和止两点)存入一个横坐标序列排序,排好后的序列中每两个相邻坐标视为一个区间,以区间为单位进行分析(这就是离散化的方法).这样一来,每次只分析那些经过该区间的建筑物(可以取区间中点来判断某个建筑是否在该区间内).将要分析的建筑物以纵坐标大小进行排序好后,一一来判断前面是否有遮挡物即可.


代码如下:

#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <string>#include <cstring>#include <vector>#include <set>#include <stack>#include <queue>#include <cmath>#include <deque>#include <map>#include <cassert>using namespace std;const int MAXN = 110;typedef long long LL;/*uva 221*/struct build{int num;double x1,x2;double y;double width;// south lengthdouble depth;// west  length【non-sense】double height;bool visible;bool operator < (const build & b) const{return this->y < b.y;}};bool ans_compare(const build & a,const build & b){if( a.x1!=b.x1 ){return a.x1<b.x1;}else{return a.y < b.y;}}int num;build b[MAXN];set<int> xpos;set<int>::iterator it1,it2;vector<build> tmp;vector<build> ans;void check(int x1,int x2){double mid = (x1+x2)/2;tmp.clear();for(int i=0; i<num; i++){if( mid>b[i].x1 && mid<b[i].x2 ){tmp.push_back(b[i]);}}sort(tmp.begin(),tmp.end());// 按y由大到小排列for(int i=0; i<tmp.size(); i++){bool flag = true;for(int j=0; j<i; j++){if( tmp[j].height >= tmp[i].height ){flag = false;}}if( flag && !b[(tmp[i].num-1)].visible ){b[(tmp[i].num-1)].visible = true;ans.push_back(b[(tmp[i].num-1)]);}}sort(ans.begin(),ans.end(),ans_compare);//cout << endl << "--------------------------------" << endl;return ;}int main(){int Case = 0;//freopen("input2.txt","r",stdin);while( scanf("%d",&num) && num!=0 ){memset(b,0,sizeof(b));xpos.clear();ans.clear();for(int i=0; i<num ;i++){cin >> b[i].x1 >> b[i].y >> b[i].width >> b[i].depth >> b[i].height;b[i].x2 = b[i].x1+b[i].width;b[i].num = i+1;xpos.insert(b[i].x1);xpos.insert(b[i].x2);}//sort(tmp.begin(),tmp.end());//for(int i=0; i<num; i++){//cout << tmp[i].num << " ";//}it1 = it2 = xpos.begin();it2++;for( ; it2!=xpos.end(); it1++,it2++){check(*it1,*it2);}if( Case>0 ) printf("\n");printf("For map #%d, the visible buildings are numbered as follows:\n",++Case);for(int i=0; i<ans.size(); i++){cout << ans[i].num ;if( i<ans.size()-1 ) cout << " ";}cout << endl;}return 0;}


0 0
原创粉丝点击