UVA 221 Urban Elevations

思路:

UVA 221 Urban Elevations

  一些解释:

  ①:建筑的排序:

  下面是以输入顺序为标号,在数组bd中的顺序:

UVA 221 Urban Elevations

  排序后在数组bd中的顺序:

  UVA 221 Urban Elevations

  以后我们比较就按这个顺序

  ②:x坐标的排序

  x的内容是每一个建筑的左边界和右边界,我们把他去重排序后,就是一个一个的坐标,相邻的x形成一个区间,

  取它的中点来判断,比如,样例输入的bd[1]就是遍历所有的区间来判断是否可见。下面附上调试截图。

  x:

  UVA 221 Urban Elevations

  sort后的x:

  UVA 221 Urban Elevations

  unique后的x:

  UVA 221 Urban Elevations

  

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 struct building {
 5     int NO;
 6     double x, y, width, depth, height;
 7     double xr;//右边界
 8 }bd[105];
 9 double x[105 * 2];
10 int n;
11 bool cmp(building & b1, building & b2)
12 {
13     if (b1.x < b2.x)
14         return true;
15     if (b1.x == b2.x&&b1.y < b2.y)
16         return true;
17     return false;
18 }
19 bool cover(int i, double mx)//看mx在不在第i个建筑范围内
20 {
21     return  ((bd[i].x <= mx) && (bd[i].xr >= mx));
22 }
23 bool visible(int i, double mx)//第i个建筑物在x=mx是否可见
24 {
25     if (!cover(i, mx))
26         return false;
27     for (int j = 0; j < n; j++)//遍历所有建筑,寻找第i个建筑[南方]的建筑看会不会被挡住
28     {
29         if (bd[j].y < bd[i].y&&bd[j].height >= bd[i].height&&cover(j,mx))
30             return false;
31         /*bd[j].y < bd[i].y在此建筑的南方
32         bd[j].height >= bd[i].height,南方建筑更高
33         cover(j,mx) mx也在南方建筑范围内
34         */
35     }
36     return true;
37 }
38 int main()
39 {
40     int kase = 0;
41     while (scanf("%d", &n) && n != 0)
42     {
43         for (int i = 0; i < n; i++)
44         {
45             scanf("%lf%lf%lf", &bd[i].x, &bd[i].y, &bd[i].width);
46             scanf("%lf%lf", &bd[i].depth, &bd[i].height);
47             bd[i].NO = i+1;
48             bd[i].xr = bd[i].x + bd[i].width;
49             x[i * 2] = bd[i].x;//记录左边界
50             x[i * 2 + 1] = bd[i].xr;//右边界
51         }
52 
53         sort(bd, bd + n, cmp);
54         sort(x, x + 2 * n);
55         int m = unique(x, x + n * 2) - x;//不重复元素的个数
56         if (kase++)
57             printf("\n");
58         printf("For map #%d, the visible buildings are numbered as follows:\n%d", kase,bd[0].NO);
59         //因为第一个输出没有空格,而第一个bd肯定不会被挡住,
60         //所有先把第一个输出来.下面从1开始
61         for (int i = 1; i < n; i++)
62         {
63             bool vis = false;
64             for (int j = 0; j < m-1; j++)
65             {
66                 if (visible(i, (x[j] + x[j+1]) / 2))
67                 {
68                     vis = true;
69                     break;
70                 }
71             }
72             if (vis)
73                 printf(" %d", bd[i].NO);
74         }
75         printf("\n");
76     }
77     return 0;
78 }

 

    

 

上一篇:ISO8601格式日期获取


下一篇:寒假ACM集训复习总结Day3-helman