练习题 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 }