poj 1021 java_北大poj-1021 - osc_mervd488的个人空间 - OSCHINA - 中文开源技术交流社区...

2D-Nim

Time Limit: 1000MS

Memory Limit: 10000K

Total Submissions: 4066

Accepted: 1851

Description

The 2D-Nim board game is played on a grid, with pieces on the grid points. On each move, a player may remove any positive number of contiguous pieces in any row or column. The player who removes the last piece wins. For example, consider the left grid in the following figure.

94d5cd6ed5b6572f9705bfe42d909072.gif

The player on move may remove (A), (B), (A, B), (A, B, C), or (B,F), etc., but may not remove (A, C), (D, E), (H, I) or (B, G).

For purposes of writing 2D-Nim-playing software, a certain programmer wants to be able to tell whether or not a certain position has ever been analyzed previously. Because of the rules of 2D-Nim, it should be clear that the two boards above are essentially equivalent. That is, if there is a winning strategy for the left board, the same one must apply to the right board. The fact that the contiguous groups of pieces appear in different places and orientations is clearly irrelevant. All that matters is that the same clusters of pieces (a cluster being a set of contiguous pieces that can be reached from each other by a sequence of one-square vertical or horizontal moves) appear in each. For example, the cluster of pieces (A, B, C, F, G) appears on both boards, but it has been reflected (swapping left and right), rotated, and moved. Your task is to determine whether two given board states are equivalent in this sense or not.

Input

The first line of the input file contains a single integer t (1 ≤ t ≤ 10), the number of test cases, followed by the input data for each test case. The first line of each test case consists of three integers W, H, and n (1 ≤ W, H ≤ 100). W is the width, and H is the height of the grid in terms of the number of grid points. n is the number of pieces on each board. The second line of each test case contains a sequence of n pairs of integers xi , yi, giving the coordinates of the pieces on the first board (0 ≤ xi < W and 0 ≤ yi < H). The third line of the test case describes the coordinates of the pieces on the second board in the same format.

Output

Your program should produce a single line for each test case containing a word YES or NO indicating whether the two boards are equivalent or not.

Sample Input

2

8 5 11

0 0 1 0 2 0 5 0 7 0 1 1 2 1 5 1 3 3 5 2 4 4

0 4 0 3 0 2 1 1 1 4 1 3 3 3 5 2 6 2 7 2 7 4

8 5 11

0 0 1 0 2 0 5 0 7 0 1 1 2 1 5 1 3 3 6 1 4 4

0 4 0 3 0 2 1 1 1 4 1 3 3 3 5 2 6 2 7 2 7 4

Sample Output

YES

NO

Source

Tehran 2002, First Iran Nationwide Internet Programming Contest

分析:

需要依据题目,提取图像特征,特征一致则为YES,特征不一致则为NO。

解题:

提取了2个特征:

1)每一个点的邻接关系:统计四个方向上邻接点数量分布,即有0、1、2、3、4个点相邻的数量。

2)点的连通量:在纵向和横向两个方向上,统计连线点的分布,即有1、2、...、99、100个点连成一线的数量。

PS:这两个条件为必要不充分条件。discus中有用例我没跑过,但是poj AC了,poj的数据弱了。至于充分条件,目前我还没想出如何证明。

1 #include

2 #include

3 #include

4

5 typedef struct

6 {7 intwidth;8 intheight;9 intnum;10 int map[2][100][100];11 }Picture;12

13 typedef struct

14 {15 intx;16 inty;17 intfactor;18 }Piont;19

20 Picture pic;21 Piont points[2][10000];22 int factorCnt[2][5];23 int connectCnt[2][101];24 int connectMax[2];25

26 voidInput()27 {28 int i, j, x, y = 0;29 memset(&pic, 0, sizeof(pic));30 scanf("%d %d %d", &pic.width, &pic.height, &pic.num);31

32 for(j = 0; j < 2; j++)33 {34 for(i = 0; i < pic.num; i++)35 {36 scanf("%d %d", &x, &y);37 pic.map[j][y][x] = 1;38 points[j][i].x =x;39 points[j][i].y =y;40 }41 }42 /*

43 for(j = 0; j < 2; j++)44 {45 for(y = pic.height-1; y >= 0; y--)46 {47 for(x = 0; x < pic.width; x++)48 {49 printf("%d ", pic.map[j][y][x]);50 }51 printf("\n");52 }53 printf("------------------------\n");54 }55 */

56 }57

58 voidCalcFactor()59 {60 inti, j, x, y, factor;61 memset(factorCnt, 0, sizeof(factorCnt));62 for(j = 0; j < 2; j++)63 {64 for(i = 0; i < pic.num; i++)65 {66 x =points[j][i].x;67 y =points[j][i].y;68 factor = (x > 0) ? pic.map[j][y][x-1] : 0;69 factor += (x < pic.width-1) ? pic.map[j][y][x+1] : 0;70 factor += (y > 0) ? pic.map[j][y-1][x] : 0;71 factor += (y < pic.height-1) ? pic.map[j][y+1][x] : 0;72 points[j][i].factor =factor;73 factorCnt[j][factor]++;74 }75 }76 /*

77 for(j = 0; j < 2; j++)78 {79 for(i = 0; i < pic.num; i++)80 {81 printf("%d ", points[j][i].factor);82 }83 printf("\n");84 }85 printf("------------------------\n");86 */

87 }88

89 voidCheckResult()90 {91 int i, j = 0;92 for(i = 0; i < 5; i++)93 {94 if(factorCnt[0][i] != factorCnt[1][i]) break;95 }96

97 if(connectMax[0] != connectMax[1])98 {99 printf("NO\n");100 return;101 }102

103 for(j = 0; j < connectMax[0]; j++)104 {105 if(connectCnt[0][j] != connectCnt[1][j]) break;106 }107

108 if(i != 5 || j != connectMax[0])109 {110 printf("NO\n");111 }112 else

113 {114 printf("YES\n");115 }116 }117

118 voidCalcConnect()119 {120 intj, x, y, connect;121 memset(connectMax, 0, sizeof(connectMax));122 memset(connectCnt, 0, sizeof(connectCnt));123 for(j = 0; j < 2; j++)124 {125 for(y = 0; y < pic.height; y++)126 {127 for(x = 0; x < pic.width; x++)128 {129 if(pic.map[j][y][x] != 1) continue;130 connect = 1;131 while(++x < pic.width && pic.map[j][y][x] == 1)132 {133 connect++;134 }135 connectCnt[j][connect]++;136 if(connect > connectMax[j]) connectMax[j] =connect;137 }138 }139

140 for(x = 0; x < pic.width; x++)141 {142 for(y = 0; y < pic.height; y++)143 {144 if(pic.map[j][y][x] != 1) continue;145 connect = 1;146 while(++y < pic.height && pic.map[j][y][x] == 1)147 {148 connect++;149 }150 connectCnt[j][connect]++;151 if(connect > connectMax[j]) connectMax[j] =connect;152 }153 }154 }155 }156

157 voidProc()158 {159 CalcFactor();160 CalcConnect();161 CheckResult();162 }163

164 intmain()165 {166 int num = 0;167 scanf("%d", &num);168 while(num--)169 {170 Input();171 Proc();172 }173 return 0;174 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值