题目:
2D-Nim棋盘游戏在网格上进行,网格点上有碎片。在每次移动中,玩家可以移除任何行或列中任何正数的连续片段。删除最后一块的玩家获胜。例如,请考虑下图中的左侧网格。
移动中的玩家可以移除(A),(B),(A,B),(A,B,C)或(B,F)等,但可以不移除(A,C),(D ,E),(H,I)或(B,G)。
为了编写2D-Nim播放软件,某个程序员希望能够判断某个位置是否曾经被分析过。由于2D-Nim的规则,应该清楚的是上面的两块板基本上是等价的。也就是说,如果左棋盘有获胜策略,那么同一棋盘必须适用于正确的棋盘。事实上,连续的片段出现在不同的地方和方向上显然是无关紧要的。重要的是,每个部分中出现相同的碎片簇(簇是一组连续的碎片,可以通过一个方形的垂直或水平移动的顺序彼此到达)。例如,片组(A,B,C,F,G)出现在两个板上,但它已被反射(左右交换),旋转和移动。您的任务是确定两个给定的电路板状态在这个意义上是否相同。
输入
输入文件的第一行包含一个整数t(1≤t≤10),测试用例的数量,后跟每个测试用例的输入数据。每个测试用例的第一行由三个整数W,H和n(1≤W,H≤100)组成。 W是宽度,H是网格点数的网格高度。 n是每块板上的件数。每个测试用例的第二行包含n对整数xi,yi的序列,给出第一块板上的块的坐标(0≤xi<W且0≤yi<H)。测试用例的第三行以相同的格式描述了第二块板上的块的坐标。
输出
您的程序应为每个测试用例生成一行,其中包含单词YES或NO,指示两个板是否相同。
样例输入
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
样例输出
是
没有
为了编写2D-Nim播放软件,某个程序员希望能够判断某个位置是否曾经被分析过。由于2D-Nim的规则,应该清楚的是上面的两块板基本上是等价的。也就是说,如果左棋盘有获胜策略,那么同一棋盘必须适用于正确的棋盘。事实上,连续的片段出现在不同的地方和方向上显然是无关紧要的。重要的是,每个部分中出现相同的碎片簇(簇是一组连续的碎片,可以通过一个方形的垂直或水平移动的顺序彼此到达)。例如,片组(A,B,C,F,G)出现在两个板上,但它已被反射(左右交换),旋转和移动。您的任务是确定两个给定的电路板状态在这个意义上是否相同。
输入
输入文件的第一行包含一个整数t(1≤t≤10),测试用例的数量,后跟每个测试用例的输入数据。每个测试用例的第一行由三个整数W,H和n(1≤W,H≤100)组成。 W是宽度,H是网格点数的网格高度。 n是每块板上的件数。每个测试用例的第二行包含n对整数xi,yi的序列,给出第一块板上的块的坐标(0≤xi<W且0≤yi<H)。测试用例的第三行以相同的格式描述了第二块板上的块的坐标。
输出
您的程序应为每个测试用例生成一行,其中包含单词YES或NO,指示两个板是否相同。
样例输入
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
样例输出
是
没有
#include <iostream> using namespace std; bool map[101][101]; int W, H, n; struct dot { int x, y; }dots[100010]; int dot1[10000], dot2[10000]; void quicksort(int left, int right, int *dotx) { int i, j, temp; if (left < right) { i = left, j = right, temp = dotx[left]; while (i < j) { while (i < j&&dotx[j] >= temp) j--; dotx[i] = dotx[j]; while (i < j&&dotx[i] <= temp) i++; dotx[j] = dotx[i]; } dotx[i] = temp; quicksort(left, j - 1, dotx); quicksort(j + 1, right, dotx); } } void Count(int *dot, int i) { int x, y, sum; sum = 0; x = dots[i].x; y = dots[i].y; y--; while (map[x][y] && y >= 0) //统计左边点的个数 { sum++; y--; } y = dots[i].y; y++; while (map[x][y] && y < H) //统计右边点的个数 { sum++; y++; } y = dots[i].y; x--; while (map[x][y] && x >= 0) //统计下面点的个数 { sum++; x--; } x = dots[i].x; x++; while (map[x][y] && x < W) //统计上面点的个数 { sum++; x++; } dot[i] = sum; } int main() { int t; cin >> t; int sum1, sum2; while (t--) { sum1 = sum2 = 0; memset(map, false, sizeof(map)); cin >> W >> H >> n; for (int i = 1; i <= n; i++) //输入第一组点 { cin >> dots[i].x >> dots[i].y; map[dots[i].x][dots[i].y] = true; } for (int i = 1; i <= n; i++) Count(dot1, i), sum1 += dot1[i]; //第一张图的连续点数 memset(map, false, sizeof(map)); for (int i = 1; i <= n; i++) //输入第二组点 { cin >> dots[i].x >> dots[i].y; map[dots[i].x][dots[i].y] = true; } for (int i = 1; i <= n; i++) Count(dot2, i), sum2 += dot2[i]; //第二张图的连续点数 if (sum1 != sum2) cout << "NO" << endl; else { quicksort(1, n, dot1); quicksort(1, n, dot2); int flag = 1; for (int i = 1; i <= n; i++) { if (dot1[i] != dot2[i]) { //我之前在这里写了输出用来看数据的 //我提交的时候忘记删了,结果还对了 //不得不说这测试数据是真的水 flag = 0; break; } } if (flag) cout << "YES" << endl; else cout << "NO" << endl; } } }
来源:http://bk.bk3r.com/?f=s2gou&br3rd=1&wn=1&hid=99_16_16_0_&ty3=0&tryno=1509