2011年珠海赛 H题 Rolling
1 /* 2 题意:给出一个球体,桌面是红色染料,球在上面滚会染上一些线,给出滚的方向和距离,求球面上染的线将球面分成的几个块中最大块的面积 3 4 题解:模拟+建图+连通 5 因为球的半径为2/PI,因此滚动一圈恰好是4,给出的是整数的距离,说明每次滚动都是N个1/4圆的长度,然后将整个球面分成8块,每块给一个位置标记0~7,每转动1的距离,就相当于将相邻的两块分割开,就变成了求8块连通的区域在通过转动切割边之后剩下的最大的连通分量数目,因此在每次的转动模拟四个方向(转动即相当于切割),至于模拟的方法就是用0~7固定标记在球的表面,每次的转动这些标记也会跟随转动,然后把8个标记模拟放置到下一个数组当中,然后建成一个8*8的图,每个块为一个点,两个相邻的块加一条边,每一次染1/4色相当于删除一条边,可以重复删边,最后模拟完后就可以直接通过图求点数最多的连通分量的点得数目,然后乘上面积即可 6 */ 7 #include <cstdio> 8 #include <cstring> 9 #include <cmath> 10 11 const double PI = acos(-1.0); 12 13 int ball[8]; // 球转动前各个面的位置状态 14 int dir[4][8]={ 15 {4,5,1,0,7,6,2,3}, 16 {3,2,6,7,0,1,5,4}, 17 {4,0,3,7,5,1,2,6}, 18 {1,5,6,2,0,4,7,3} 19 };//从上到下方向为N,S,W,E,d[][j]表示j位置的块移动到d[][j]位置 20 21 bool vis[10]; 22 23 int dfs(int u, int map[][8]) 24 { 25 int ret = 0; 26 for(int i=0; i<8; i++) 27 { 28 if (u != i && !vis[i] && map[u][i]) 29 { 30 vis[i] =true; 31 ret += dfs(i,map); 32 } 33 } 34 return ret + 1; 35 } 36 37 int main(void) 38 { 39 int t,d; 40 char s[10]; 41 scanf("%d",&t); 42 while (t--) 43 { 44 int n; 45 scanf("%d",&n); 46 // 先建好没有去除任何边前的图 47 int map[8][8] = 48 {{0,1,0,1,1,0,0,0}, 49 {1,0,1,0,0,1,0,0}, 50 {0,1,0,1,0,0,1,0}, 51 {1,0,1,0,0,0,0,1}, 52 {1,0,0,0,0,1,0,1}, 53 {0,1,0,0,1,0,1,0}, 54 {0,0,1,0,0,1,0,1}, 55 {0,0,0,1,1,0,1,0}}; 56 for(int i=0; i<8; i++) 57 ball[i] = i; 58 while (n--) 59 { 60 scanf("%s%d",s,&d); 61 if (d >= 4) 62 d = 4 + d % 4; // 此处小坑,不能直接MOD 4,当值为4,MOD了之后就等于没有任何线加上,因此要注意 63 if (strcmp(s,"NORTH") == 0) 64 { 65 for(int i=0; i<d; i++) 66 { 67 map[ball[4]][ball[5]] = map[ball[5]][ball[4]] = 0; // 画了一条线就要删除该边 68 int tmp[8]; 69 for(int j=0; j<8; j++) 70 { 71 tmp[j] = ball[j]; 72 } 73 for(int j=0; j<8; j++) 74 { 75 ball[dir[0][j]] = tmp[j]; // 球旋转,每一块转到对应位置 76 } 77 } 78 } 79 else if (strcmp(s,"SOUTH") == 0) 80 { 81 for(int i=0; i<d; i++) 82 { 83 map[ball[6]][ball[7]] = map[ball[7]][ball[6]] = 0; 84 int tmp[8]; 85 for(int j=0; j<8; j++) 86 { 87 tmp[j] = ball[j]; 88 } 89 for(int j=0; j<8; j++) 90 { 91 ball[dir[1][j]] = tmp[j]; 92 } 93 } 94 } 95 else if (strcmp(s,"WEST") == 0) 96 { 97 for(int i=0; i<d; i++) 98 { 99 map[ball[4]][ball[7]] = map[ball[7]][ball[4]] = 0; 100 int tmp[8]; 101 for(int j=0; j<8; j++) 102 { 103 tmp[j] = ball[j]; 104 } 105 for(int j=0; j<8; j++) 106 { 107 ball[dir[2][j]] = tmp[j]; 108 } 109 } 110 } 111 else 112 { 113 for(int i=0; i<d; i++) 114 { 115 map[ball[6]][ball[5]] = map[ball[5]][ball[6]] = 0; 116 int tmp[8]; 117 for(int j=0; j<8; j++) 118 { 119 tmp[j] = ball[j]; 120 } 121 for(int j=0; j<8; j++) 122 { 123 ball[dir[3][j]] = tmp[j]; 124 } 125 } 126 } 127 } 128 int ans = -1; 129 memset(vis,false,sizeof(vis)); 130 for(int i=0; i<8; i++) 131 { 132 if (!vis[i]) 133 { 134 vis[i] = true; 135 int t = dfs(i,map); 136 if (ans < t) 137 ans = t; 138 } 139 } 140 141 printf("%.3lf\n",ans*2.0/PI); 142 } 143 return 0; 144 }
1007. Problem H Rolling
|
||
Description
It is an interesting problem. Imagine there is a ball on a boundless ground. Initially the ball is white and the ground is red. Now, the ball starts to roll on the ground, and is dyed with red by the ground. A point on the surface of the ball will turn to red when it touches the ground. Finally the ball stops and the surface of the ball may be divided into several parts. You should calculate the area of the largest part. The radius of the ball is 2 / PI (PI is circumference ratio). Input
The first line of the input is an integer T, the number of test cases (0 < T <= 10).
Then T test case followed. In each test case, the first line contains an integer N (0 <= N <= 10000), the number of rolling operation of the ball. Each of the next N line contains a string S and an integer D, separated by spaces. S will be one of {‘EAST’, ‘WEST’, ‘NORTH’, ‘SOUTH’}, means the direction of the ball rolling operation, and D means the distance of the ball rolling operation. The ball will roll on the ground with the given N operation by the order of input.
Output
For each test case, output one real, rounded to 3 decimal places, the area of the largest part of surface of the ball. Sample Input
3 1 EAST 1000000 3 NORTH 1 WEST 1 SOUTH 1 2 WEST 1 EAST 1 Sample Output
2.546 4.456 5.093 Problem Source: test_one |
||