练习题 A Building Collapse Prediction System

题目完整描述:

You want to create a system to predict collapse of old buildings. Initial durability of all buildings is given and decreased every year by 1. The buildings will collapse once its durability hits 0. When a building collapses it affects other buildings around them. This will lead to decrease in durability by 10 / (|dx| + |dy|). (Drop the decimal point) (dx, dy: distance of x and y coordinate between the collapsed building and other buildings being impacted respectively)

Initial durability >

      9
  7     
       
3     9

 

Durability after 3 years >

 

      5
  1     
       
0     3

 

N buildings are located in a square grid plate of size (W x W). Print the number of remaining buildings after K years. The image above shows the initial durability and durability after 3 years. The building at (1, 4) collapsed since its durability became 0, thus impacted buildings at coordinates (2, 2), (4, 4) and (4, 1) and their durability reduced by 3, 3 and 1, respectively.

[Input] The first line contains the number of test cases, T. The first line of each test case has N(1≤N≤105, N≤W2) and W(1≤W≤108), K(1≤K≤9). The next N lines contain x coordinate xi (1≤xi≤W), y coordinate yi (1≤yi≤W), and durability di (1≤di≤9), separated by a space.

[Output] For each test case, print ‘#x’(test case number), and the number of remaining buildings after K years.

 

Input Example

2  // T : Number of test cases

4 4 3  // N, W, K of 1st test case

2 2 7  // x1 y1 d1

4 1 9  // x2 y2 d2

4 4 9  // x3 y3 d3     

1 4 3  // x4 y4 d4

4 4 4  // N, W, K of 2nd test case

2 2 7

4 1 9

4 4 9

1 4 3  

Output Example

#1 3

#2 0

 

题解:Hash入门题目

 

参考代码:

  1 /* A Building Collapse Prediction System
  2 题意:二维W*W(10^8)中有建筑物N个(10^5),每个建筑物有初始寿命Di,每年寿命-1,寿终正寝时对周边建筑物造成寿命缩减为: 10 / (|dx| + |dy|),取整,求K年后剩余建筑物个数
  3 题解:建筑物沦陷对周边建筑物造成影响是无后效性的,已经消亡的建筑物不需考虑其他建筑物对其的影响*/
  4 #include <stdio.h>
  5 #define H 1007
  6 struct building{
  7     int x, y, d;
  8 } b[100001], q[100001];
  9 int n, w, k, tc, hd[100001], hs[1008][1008], front, rear;
 10 int hashf(int x){
 11     return 1 + x%H;
 12 }
 13 int compute(){
 14     for (int i = 1; i <= n; ++i){
 15         b[i].d -= k;
 16         if (b[i].d <= 0)q[rear++] = b[i];
 17     }
 18     while (front != rear){
 19         building bd = q[front++];
 20         int hx = hashf(bd.x / 10);
 21         int hy = hashf(bd.y / 10);
 22         for (int i = hx - 1; i <= hx + 1; ++i)
 23         for (int j = hy - 1; j <= hy + 1; ++j)
 24         for (int h = hs[i][j]; h > 0; h = hd[h]){
 25             if (b[h].d <= 0)continue;
 26             int dx = b[h].x - bd.x;
 27             int dy = b[h].y - bd.y;
 28             if (dx < 0)dx = -dx;
 29             if (dy < 0)dy = -dy;
 30             b[h].d -= 10 / (dx + dy);
 31             if (b[h].d <= 0)q[rear++] = b[h];
 32         }
 33     }
 34     return n - rear;
 35 }
 36 int main(){
 37 scanf("%d", &tc);
 38     for (int t = 1; t <= tc; ++t){
 39         scanf("%d%d%d", &n, &w, &k);
 40         for (int i = 1; i <= n; ++i)
 41             scanf("%d%d%d", &b[i].x, &b[i].y, &b[i].d);
 42         for (int i = 1; i <= n; ++i){
 43             int hx = hashf(b[i].x / 10);
 44             int hy = hashf(b[i].y / 10);
 45             hd[i] = hs[hx][hy];
 46             hs[hx][hy] = i;
 47         }
 48         front = rear = 0;
 49         printf("#%d %d\n", t, compute());
 50         for (int i = 1; i <= n; ++i) {
 51             int hx = hashf(b[i].x / 10);
 52             int hy = hashf(b[i].y / 10);
 53             hs[hx][hy] = 0;
 54         }
 55     }
 56     return 0;
 57 }
 58  
 59  另一种写法:
 60  
 61 #include <stdio.h>
 62 #define max 100007
 63 #define hash 1007
 64 int head[hash+1][hash+1];
 65 struct building{
 66     int i, j, d, next;
 67     building(int _i, int _j, int _d) :i(_i), j(_j), d(_d), next(-1){};
 68     building(){};
 69 } dead[max], bd[max];
 70 int main(void){
 71     scanf("%d", &T);
 72     for (int tc = 1; tc <= T; ++tc){
 73         scanf("%d%d%d", &N, &W, &K);
 74         front = rear = cnt = 0;
 75         for (int i = 0; i < hash; ++i)
 76         for (int j = 0; j < hash; ++j)
 77             head[i][j] = -1;
 78         for (int i = 0; i < N; ++i){
 79             scanf("%d%d%d", &x, &y, &td);
 80             building tbd(x,y,td-K);
 81             if (tbd.d>0){
 82                 bd[cnt] = tbd;
 83                 tx = x % hash;ty = y % hash;
 84                 bd[cnt].next = head[tx][ty];
 85                 head[tx][ty] = cnt++;
 86             }else{
 87                 dead[rear++] = tbd;
 88             }
 89         }
 90         while (front != rear){
 91             building in = dead[front++];
 92             x = in.i;
 93             y = in.j;
 94             for (int i = x - 10; i <= x + 10; ++i){
 95                 for (int j = y - 10; j <= y + 10; ++j){
 96                    if ((x + y - i - j) > 10 || (x - y - i + j) > 10 || (-x - y + i + j) > 10 || (-x + y + i - j) > 10 || i <= 0 || j <= 0 || i > W || j > W)continue;
 97                    tx = i % hash;
 98                    ty = j % hash;
 99                     if (head[tx][ty] < 0)continue;
100                    building *sch = &bd[head[tx][ty]];
101                    while(true){
102                        if ((sch->d>0) && (sch->i == i) && (sch->j == j)){
103                            td = (i>x ? (i - x) : (x - i)) + (j>y ? (j - y) : (y - j)); //如果没有限制条件sch->d>0 还应该确保除数不为零                                                sch->d = sch->d - 10 / td;
104                            if (sch->d>0)break;
105 //并不对已经消亡的点做删除操作,链表结构不变化,只是增加判断条件d>0
106                            dead[rear++] = *sch;
107                            --cnt;
108                            break;
109                        }
110                        if (sch->next < 0) break;
111                        sch = &bd[sch->next];
112                    };
113                 }
114             }
115         }
116         printf("#%d %d\n", tc, cnt);
117     }
118     return 0;
119 }

 

 

posted @ 2017-12-28 16:55  proscientist  阅读(246)  评论(0编辑  收藏  举报