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. 2018-2019-2 20175317 实验二《Java面向对象程序设计》实验报告

    2018-2019-2 20175317 实验二<Java面向对象程序设计>实验报告 一.实验步骤及内容 面向对象程序设计-1 参考 http://www.cnblogs.com/roce ...

  2. jmeter实践之数据库参数传递

    一.需求: 1.业务需求:根据手机号到数据库中查看用户id,再根据用户id查看该注册用户下关联的健康成员. 2.参数化分析 1)需要根据不同的手机号进行查询,所以手机号需要进行参数化 2)用户id要作 ...

  3. 《R语言入门与实践》第七章:程序

    前言 这一章讲了程序设计的相关知识,经过了: 算法分析 编码 得到最后的程序. if 语句 格式:if (this) {that} else if { another} else { another ...

  4. 创建springboot项目

    springboot 就是为简化spring的创建 配置 部署 运行 而创建的. springboot 直接引入依赖jar包 就行了,无须配置xml 一 创建springboot 1.创建一个mave ...

  5. f-stack中ipc传递指针从应用中读取信息时挂掉

    f-stack中ipc传递指针从应用中读取信息时挂掉 如:创建bridge0./ifconfig bridge0 create./ifconfig f-stack-0 down./ifconfig f ...

  6. cron定时任务

    1.确认系统安装了cron rpm -aq | grep crontabs 2.认识cron时间格式 3.生成定时任务 crontab -e #进入任务命令编辑模式 30 7,12,20 * * * ...

  7. java的equals()与hashCode()以及包装类中的实现

    1. hashcode 1.1 hashcode来源 1.2 hashcode的形式 1.3 hashcode目的 1.4 hashcode规则 1.5 hashcode作用体现 1.6 重写hash ...

  8. webpack打包vue项目,资源路径如何从绝对路径改为相对路径?css中的图片资源如何修改配置?

    资源相对引用路径 问题描述 一般情况下,通过webpack+vuecli默认打包的css.js等资源,路径都是绝对的. 但当部署到带有文件夹的项目中,这种绝对路径就会出现问题,因为把配置的static ...

  9. 43. Multiply Strings字符串相乘

    网址:https://leetcode.com/problems/multiply-strings/submissions/ 参考:https://leetcode.com/problems/mult ...

  10. springboot 默认异常处理

    SpringBoot默认有自定义异常处理的体系,在做SpringBoot项目的时候,如果是抛出了运行时异常,springBoot并会对异常进行处理,返回如下异常信息: { "timestam ...