离散化思想就是化无限为有限。
具体到这道题来说,building露出的区间一定是有限的,那么只需要在这些区间中取一个点,判断building在这个区间中是否会露出
学习到的东西:
离散化思想
unique函数的使用
给结构体定义小于运算符
全局变量绝对不能再局部再次定义,否则可能会引起意想不到的错误
下面附上AC代码:
//这道题目展示了离散化的思想和unique函数的使用方式,以及对于struct定义《运算符之后的排序的使用 #include<cstdio> #include<iostream> #include<algorithm> #include<vector> using namespace std; int num_building; const int maxn = 100 + 5; struct building { int id; double x,y,width,deep,height; bool operator < (building b) { return (x < b.x) || (x == b.x && y < b.y); } }b[maxn]; //double V[2 * maxn + 5]; vector<double>V; int num_set; bool visible(int x,double x_mid) { if(x_mid < b[x].x || x_mid > b[x].x + b[x].width) return false; for(int i = 0;i < num_set;i++) { if(b[i].height >= b[x].height && b[i].y < b[x].y && b[i].x < x_mid && ((b[i].x + b[i].width) > x_mid)) return false; } return true; } void print_V() { for(int i = 0;i<num_set;i++) { printf(" %lf ",V[i]); } printf("\n\n"); } int main() { #ifdef local freopen("input.txt","r",stdin); #endif int kase = 0; while(scanf("%d",&num_building)&&num_building) { if(kase) printf("\n"); printf("For map #%d, the visible buildings are numbered as follows:\n",++kase); for(int i_1 = 0;i_1 < num_building;i_1++) { scanf("%lf%lf%lf%lf%lf",&b[i_1].x,&b[i_1].y,&b[i_1].width,&b[i_1].deep,&b[i_1].height); b[i_1].id = i_1 + 1; V.push_back(b[i_1].x); V.push_back(b[i_1].x + b[i_1].width); //V[2 * i_1] = b[i_1].x; //V[2 * i_1 + 1] = b[i_1].x + b[i_1].width; } sort(V.begin(),V.end()); //sort(V,V + 2 * num_building); //num_set = unique(V,V + 2 * num_building) - V;//全局变量千万不能在局部重新定义 num_set = unique(V.begin(),V.end()) - V.begin(); //print_V(); sort(b,b + num_building); int cnt = 0; for(int i_2 = 0;i_2 < num_building;i_2++) { for(int i_3 = 0; i_3 < num_set - 1;i_3++) { if(visible(i_2,((V[i_3] + V[i_3 + 1]) / 2))) { if(cnt) printf(" "); cnt++; printf("%d",b[i_2].id); break; } } } printf("\n"); } return 0; }