北大oj1021——2D-Nim

http://poj.org/problem?id=1021

2D-Nim

| Time Limit: 1000MS | | Memory Limit: 10000K |

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.
[图片上传中...(image-767dcd-1621567853205-0)]
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</pre>

Sample Output

YES
NO

想通了这道题也很简单,遍历每个点,计算该点的上下左右各方向有多少点,来判断图形是否相等。
其实网上说的每个点上下所有点加起来就能判断是不对的。
比如:
1 0 0
1 0 0
1 0 1
1 1 1
————————————————
1 0 0
1 1 1
1 0 1
1 0 0
但是数据比较水过了。

#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;

int pos[101][101];
int pos_index[10001][2];
map<vector<int>, int> pos_type[2];
int w, h, cnt;

enum 
{
    direction_left = 0,
    direction_top,
    direction_right,
    direction_bottom,
};

int findAllPoint(int direction, int _h, int _w) {
    if (direction == direction_left) {
        if (_w - 1 >= 0 && pos[_h][_w - 1]) {
            return 1 + findAllPoint(direction, _h, _w - 1);
        }
    }
    else if (direction == direction_top) {
        if (_h - 1 >= 0 && pos[_h - 1][_w]) {
            return 1 + findAllPoint(direction, _h - 1, _w);
        }
    }
    else if (direction == direction_right) {
        if (_w + 1 < w && pos[_h][_w + 1]) {
            return 1 + findAllPoint(direction, _h, _w + 1);
        }
    }
    else if (direction == direction_bottom) {
        if (_h + 1 < h && pos[_h + 1][_w]) {
            return 1 + findAllPoint(direction, _h + 1, _w);
        }
    }
    return 0;
}

int main() {
    int t;
    cin >> t;
    for (int _t = 0; _t < t; _t ++) {
        cin >> w >> h >> cnt;
        
        pos_type[0].clear();
        pos_type[1].clear();
        for (int index = 0; index <= 1; index++) {
            memset(pos, 0, sizeof(pos));
            memset(pos_index, 0, sizeof(pos_index));
            for (int _cnt = 0; _cnt < cnt; _cnt++) {
                int posX, posY;
                cin >> posX >> posY;
                pos[posY][posX] = 1;
                pos_index[_cnt][0] = posX;
                pos_index[_cnt][1] = posY;
            }
            for (int _cnt = 0; _cnt < cnt; _cnt++) {
                int left = findAllPoint(direction_left, pos_index[_cnt][1], pos_index[_cnt][0]);
                int top = findAllPoint(direction_top, pos_index[_cnt][1], pos_index[_cnt][0]);
                int right = findAllPoint(direction_right, pos_index[_cnt][1], pos_index[_cnt][0]);
                int bottom = findAllPoint(direction_bottom, pos_index[_cnt][1], pos_index[_cnt][0]);
                int directionArray[4] = { left , top , right, bottom };
                vector<int> vec_type;
                vec_type.push_back(1);
                sort(directionArray, directionArray + 4);
                for (int i = 3; i >= 0; i--) {
                    if (directionArray[i]) {
                        vec_type.push_back(directionArray[i]);
                    }
                }
                if (pos_type[index][vec_type]) {
                    pos_type[index][vec_type] = pos_type[index][vec_type] + 1;
                }
                else {
                    pos_type[index][vec_type] = 1;
                }
            }
        }

        bool isRight = true;
        map<vector<int>, int>::iterator it_0;
        map<vector<int>, int>::iterator it_1;
        for (it_0 = pos_type[0].begin(), it_1 = pos_type[1].begin(); it_0 != pos_type[0].end(), it_1 != pos_type[1].end(); it_0++, it_1++) {
            if ((it_0->first) != (it_1->first) || (it_0->second) != (it_1->second)) {
                isRight = false;
                break;
            }
        }
        if (isRight) {
            cout << "YES" << endl;
        }
        else {
            cout << "NO" << endl;
        }
    }
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 表情是什么,我认为表情就是表现出来的情绪。表情可以传达很多信息。高兴了当然就笑了,难过就哭了。两者是相互影响密不可...
    Persistenc_6aea阅读 128,455评论 2 7
  • 16宿命:用概率思维提高你的胜算 以前的我是风险厌恶者,不喜欢去冒险,但是人生放弃了冒险,也就放弃了无数的可能。 ...
    yichen大刀阅读 11,653评论 0 4

友情链接更多精彩内容