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.


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的数据弱了。至于充分条件,目前我还没想出如何证明。
 
 #include <stdio.h>
#include <stdlib.h>
#include <string.h> typedef struct
{
int width;
int height;
int num;
int map[][][];
}Picture; typedef struct
{
int x;
int y;
int factor;
}Piont; Picture pic;
Piont points[][];
int factorCnt[][];
int connectCnt[][];
int connectMax[]; void Input()
{
int i, j, x, y = ;
memset(&pic, , sizeof(pic));
scanf("%d %d %d", &pic.width, &pic.height, &pic.num); for(j = ; j < ; j++)
{
for(i = ; i < pic.num; i++)
{
scanf("%d %d", &x, &y);
pic.map[j][y][x] = ;
points[j][i].x = x;
points[j][i].y = y;
}
}
/*
for(j = 0; j < 2; j++)
{
for(y = pic.height-1; y >= 0; y--)
{
for(x = 0; x < pic.width; x++)
{
printf("%d ", pic.map[j][y][x]);
}
printf("\n");
}
printf("------------------------\n");
}
*/
} void CalcFactor()
{
int i, j, x, y, factor;
memset(factorCnt, , sizeof(factorCnt));
for(j = ; j < ; j++)
{
for(i = ; i < pic.num; i++)
{
x = points[j][i].x;
y = points[j][i].y;
factor = (x > ) ? pic.map[j][y][x-] : ;
factor += (x < pic.width-) ? pic.map[j][y][x+] : ;
factor += (y > ) ? pic.map[j][y-][x] : ;
factor += (y < pic.height-) ? pic.map[j][y+][x] : ;
points[j][i].factor = factor;
factorCnt[j][factor]++;
}
}
/*
for(j = 0; j < 2; j++)
{
for(i = 0; i < pic.num; i++)
{
printf("%d ", points[j][i].factor);
}
printf("\n");
}
printf("------------------------\n");
*/
} void CheckResult()
{
int i, j = ;
for(i = ; i < ; i++)
{
if(factorCnt[][i] != factorCnt[][i]) break;
} if(connectMax[] != connectMax[])
{
printf("NO\n");
return;
} for(j = ; j < connectMax[]; j++)
{
if(connectCnt[][j] != connectCnt[][j]) break;
} if(i != || j != connectMax[])
{
printf("NO\n");
}
else
{
printf("YES\n");
}
} void CalcConnect()
{
int j, x, y, connect;
memset(connectMax, , sizeof(connectMax));
memset(connectCnt, , sizeof(connectCnt));
for(j = ; j < ; j++)
{
for(y = ; y < pic.height; y++)
{
for(x = ; x < pic.width; x++)
{
if(pic.map[j][y][x] != ) continue;
connect = ;
while(++x < pic.width && pic.map[j][y][x] == )
{
connect++;
}
connectCnt[j][connect]++;
if(connect > connectMax[j]) connectMax[j] = connect;
}
} for(x = ; x < pic.width; x++)
{
for(y = ; y < pic.height; y++)
{
if(pic.map[j][y][x] != ) continue;
connect = ;
while(++y < pic.height && pic.map[j][y][x] == )
{
connect++;
}
connectCnt[j][connect]++;
if(connect > connectMax[j]) connectMax[j] = connect;
}
}
}
} void Proc()
{
CalcFactor();
CalcConnect();
CheckResult();
} int main()
{
int num = ;
scanf("%d", &num);
while(num--)
{
Input();
Proc();
}
return ;
}
 

北大poj-1021的更多相关文章

  1. 北大POJ题库使用指南

    原文地址:北大POJ题库使用指南 北大ACM题分类主流算法: 1.搜索 //回溯 2.DP(动态规划)//记忆化搜索 3.贪心 4.图论 //最短路径.最小生成树.网络流 5.数论 //组合数学(排列 ...

  2. poj 1021矩阵平移装换后是否为同一个矩阵

    2D-Nim Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 3081   Accepted: 1398 Descriptio ...

  3. POJ 1021 2D-Nim

    Description The 2D-Nim board game is played on a grid, with pieces on the grid points. On each move, ...

  4. POJ 1021 人品题

    报告见代码.. #include <iostream> #include <cstdio> #include <cstring> #include <algo ...

  5. 【Java】深深跪了,OJ题目Java与C运行效率对比(附带清华北大OJ内存计算的对比)

    看了园友的评论之后,我也好奇清橙OJ是怎么计算内存占用的.重新测试的情况附在原文后边. -------------------------------------- 这是切割线 ----------- ...

  6. POJ 1861 Network (Kruskal算法+输出的最小生成树里最长的边==最后加入生成树的边权 *【模板】)

    Network Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 14021   Accepted: 5484   Specia ...

  7. 各大OJ

    北大POJ 杭电HDU 浙大ZOj 蓝桥杯 PAT

  8. leetcode学习笔记--开篇

    1 LeetCode是什么? LeetCode是一个在线的编程测试平台,国内也有类似的Online Judge平台.程序开发人员可以通过在线刷题,提高对于算法和数据结构的理解能力,夯实自己的编程基础. ...

  9. OJ题目JAVA与C运行效率对比

    [JAVA]深深跪了,OJ题目JAVA与C运行效率对比(附带清华北大OJ内存计算的对比) 看了园友的评论之后,我也好奇清橙OJ是怎么计算内存占用的.重新测试的情况附在原文后边. ----------- ...

  10. C++ 指针常见用法小结

    1. 概论 2.指针基础 3. 指针进阶 4. 一维数组的定义与初始化 5. 指针和数组 6. 指针运算 7. 多维数组和指针 8. 指针形参 9. 数组形参 10. 返回指针和数组 11. 结语   ...

随机推荐

  1. python+selenium的web自动化测试之二(Jenkins自动执行)

    上一篇需要手工去到cmd下执行脚本,不符合自动化测试的终极目标.现我们集成到Jenkins上,通过Jenkins一键执行或定时任务执行. 参考: https://www.cnblogs.com/ces ...

  2. 『Python』为什么调用函数会令引用计数+2

    一.问题描述 Python中的垃圾回收是以引用计数为主,分代收集为辅,引用计数的缺陷是循环引用的问题.在Python中,如果一个对象的引用数为0,Python虚拟机就会回收这个对象的内存. sys.g ...

  3. python3读写csv文件

    python读取CSV文件   python中有一个读写csv文件的包,直接import csv即可.利用这个python包可以很方便对csv文件进行操作,一些简单的用法如下. 1. 读文件 csv_ ...

  4. Vant-Weapp小程序+商城案例

    功能还在进一步完善中,欢迎扫一扫提出宝贵意见! 详细信息可进群沟通:

  5. 世界各国GDP动态排名可视化实现(基于d3.js)

    一.说明 之前在抖音上看到GDP等各种排名的可视化,一直想知道是怎么实现的.之前也有研究过一次,但觉得太麻烦放弃了,昨天又心痒难耐研究了一翻. 先是看到这篇文章说是有人基于d3.js实现:https: ...

  6. Linux—shell中$(( ))、$( )、``与${ }的区别

    命令替换 在bash中,$( )与` `(反引号)都是用来作命令替换的.命令替换与变量替换差不多,都是用来重组命令行的,先完成引号里的命令行,然后将其结果替换出来,再重组成新的命令行. exp 1 [ ...

  7. post传递中文时,可以使用urlEncode编码进行转码

    http://tool.chinaz.com/tools/urlencode.aspx

  8. implode() 数组元素组合函数

    定义和用法 implode() 函数把数组元素组合为一个字符串. 语法:implode(separator,array); 说明 虽然 separator 参数是可选的.但是为了向后兼容,推荐您使用使 ...

  9. java基础概念

    jre是java运行环境 jdk是java开发工具包 java源文件←编译class字节码文件←运行结构

  10. 电子签名在K2中的应用

    全球越来越多的企业开始使用电子签名(即eSignatures),在减少碳排放的同时简化业务流程,提高文档安全性,便于记录保存,并降低企业成本.在美国法律下,电子签名具备等同于手写签名的法律效力. 什么 ...