题目来源:http://poj.org/problem?id=1021

题目大意:

  有一种在棋盘上玩的游戏,每一步,一个玩家可以从棋盘上拿走连续行或列的棋子。谁拿到最后一颗棋子就胜利。如下图所示的棋盘,玩家可以拿走 (A), (B), (A, B), (A, B, C), 或 (B,F),等,但不能拿走(A, C), (D, E), (H, I) 或(B, G)。

  仔细看上面两个棋盘,会发现其实他们是等价的。左边棋盘的取胜策略也可以用到右边的棋盘上。两盘棋子的连续块的形状是等价的,可以通过旋转、镜像和平移进行映射。程序的任务是判断两个棋盘是否等价。

输入:第一行为测试用例数。每个测试用例的第一行有三个整数W,H和n(1,<=W,H<=100).W和H为棋盘宽和高,n是棋盘上棋子个数。第二行有n对整数。xi,yi表示第一个棋盘棋子的坐标。(0<=xi<=W,0<=yi<=H).第三行为第二个棋盘的棋子分布。

输出:若两棋盘等价输出YES,否则输出NO。


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

牛人给出的方法:求出两个棋盘中每个有点的位置的度数(该点向4个方向可以走的步数之和),分别对两个棋盘棋子按度数排序,若两个序列相等输入YES,否则NO。(图形变换后,每个点的度数不变)

 //////////////////////////////////////////////////////////////////////////
// POJ1021 2D-Nim
// Memory: 428K Time: 16MS
// Language: C++ Result: Accepted
////////////////////////////////////////////////////////////////////////// #include <iostream>
using namespace std;
class Point {
public:
bool t;
int degree;
}; int compare(const void * a, const void * b) {
return (*(Point *)a).degree - (*(Point *)b).degree;
} int main() {
int ncase;
cin >> ncase;
for (int caseNo = ; caseNo <= ncase; ++caseNo) {
int H, W, n;
Point points1[ * ];
Point points2[ * ]; cin >> W >> H >> n;
for (int w = ; w < W; ++w) {
for (int h = ; h < H; ++h) {
points1[h * W + w].t = false;
points1[h * W + w].degree = ;
points2[h * W + w].t = false;
points2[h * W + w].degree = ; }
}
for (int i = ; i < n; ++i) {
int w, h;
cin >> w >> h;
points1[h * W + w].t = true;
}
for (int i = ; i < n; ++i) {
int w, h;
cin >> w >> h;
points2[h * W + w].t = true;
}
for (int w = ; w < W; ++w) {
for (int h = ; h < H; ++h) {
if (points1[h * W + w].t == true) {
int i = ;
while (h + i < H) {
if (points1[(h + i) * W + w].t == true) {
++points1[h * W + w].degree;
++i;
} else {
break;
}
}
i = ;
while (h - i >= ) {
if (points1[(h - i) * W + w].t == true) {
++points1[h * W + w].degree;
++i;
} else {
break;
}
}
i = ;
while (w + i < W) {
if (points1[h * W + w + i].t == true) {
++points1[h * W + w].degree;
++i;
} else {
break;
}
}
i = ;
while (w - i >= ) {
if (points1[h * W + w - i].t == true) {
++points1[h * W + w].degree;
++i;
} else {
break;
}
}
}
if (points2[h * W + w].t == true) {
int i = ;
while (h + i < H) {
if (points2[(h + i) * W + w].t == true) {
++points2[h * W + w].degree;
++i;
} else {
break;
}
}
i = ;
while (h - i >= ) {
if (points2[(h - i) * W + w].t == true) {
++points2[h * W + w].degree;
++i;
} else {
break;
}
}
i = ;
while (w + i < W) {
if (points2[h * W + w + i].t == true) {
++points2[h * W + w].degree;
++i;
} else {
break;
}
}
i = ;
while (w - i >= ) {
if (points2[h * W + w - i].t == true) {
++points2[h * W + w].degree;
++i;
} else {
break;
}
}
}
}
}
qsort(points1, H * W, sizeof(Point), compare);
qsort(points2, H * W, sizeof(Point), compare);
bool ok = true;
for (int i = ; i < H * W; ++i) {
if (points1[i].degree != points2[i].degree) {
ok = false;
break;
}
}
if (ok) {
cout << "YES" << endl;
} else {
cout << "NO" << endl;
}
}
system("pause");
return ;
}

POJ1021 2D-Nim的更多相关文章

  1. 一位学长的ACM总结(感触颇深)

    发信人: fennec (fennec), 信区: Algorithm 标 题: acm 总结 by fennec 发信站: 吉林大学牡丹园站 (Wed Dec 8 16:27:55 2004) AC ...

  2. 狗狗40题~ (Volume C)

    A - Triangles 记忆化搜索呗.搜索以某三角形为顶的最大面积,注意边界情况. #include <stdio.h> #include <cstring> #inclu ...

  3. 2D、3D形变

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 17.0px Monaco; color: #a5b2b9 } span.Apple-tab-span { ...

  4. CSS 3学习——transform 2D转换

    首先声明一点,transform属性不为none的元素是它的定位子元素(绝对定位和固定定位)的包含块,而且对内创建一个新的层叠上下文. 注意:可以通过 transform-box 属性指定元素的那个盒 ...

  5. UWP简单示例(三):快速开发2D游戏引擎

    准备 IDE:VisualStudio 2015 Language:VB.NET/C# 图形API:Win2D MSDN教程:UWP游戏开发 游戏开发涉及哪些技术? 游戏开发是一门复杂的艺术,编码方面 ...

  6. 赠书:HTML5 Canvas 2d 编程必读的两本经典

    赠书:HTML5 Canvas 2d 编程必读的两本经典 这两年多一直在和HTML5 Canvas 打交道,也带领团队开发了世界首款基于HTML5 Canvas 的演示文档工具---AxeSlide( ...

  7. egret3D与2D混合开发,画布尺寸不一致的问题

    egret3d的GUI目前还没有,在做3d游戏的时候没有UI可用,只能使用egret2d的EUI组件库,egret3d与egret2d混合开发,canvas3d的大小与位置与canvas2d并没有重合 ...

  8. IOS 2D游戏开发框架 SpriteKit-->续(创建敌对精灵)

    这次包括之后讲的spritekit 我都会围绕一个案例来说,这个案例就是一个简单的2d飞机大战游戏,今天这里我讲创建敌对精灵,就是敌对飞机,敌对飞机不停的被刷新到屏幕上.....当然这里涉及到的类其实 ...

  9. 2D动画的制作

    通过css3的transform  transition可以实现平移,旋转,缩放,拉伸等效果 1.缩放 -webkit-transform: scale(1); -moz-transform: sca ...

  10. 2D banner

    1.这是我第一次发博客咯!看到本文章后不喜勿喷,有什么需要改进的地方请多多指教! 2.今天和大家分享一下2D banner,代码如下,注释都有.因为本地测试和上传到博客环境不太一样,样式变化比较大,样 ...

随机推荐

  1. BZOJ5461: [PKUWC2018]Minimax

    BZOJ5461: [PKUWC2018]Minimax https://lydsy.com/JudgeOnline/problem.php?id=5461 分析: 写出\(dp\)式子:$ f[x] ...

  2. 对存在JavaScript隐式类型转换的四种情况的总结

    一般存在四种情况,JavaScript会对变量的数据类型进行转换. 目录 * if中的条件会被自动转为Boolean类型 * 会被转为false的数据 * 会被转为true的数据 * 参与+运算都会被 ...

  3. python日志轮转RotatingFileHandler在django中的一个bug

    简介 大量过时的日志会占用硬盘空间,甚至长时间运行不注意会占满硬盘导致宕机,那么就可以使用内建logging模块根据文件大小(logging.handlers.RotatingFileHandler) ...

  4. WSGI服务与django的关系

    WSGI接口 wsgi是将python服务器程序连接到web服务器的通用协议.uwsgi是独立的实现了wsgi协议的服务器.   web服务器 服务端程序 简化版的WSGI架构 服务端程序(类似dja ...

  5. scrollHeight

    scrollHeight=显示内容高度+隐藏内容高度 参考: https://developer.mozilla.org/en-US/docs/Web/API/Element.scrollHeight ...

  6. MongoDB分析工具之二:MongoDB分析器Profile

    MongoDB优化器profile 在MySQL 中,慢查询日志是经常作为我们优化数据库的依据,那在MongoDB 中是否有类似的功能呢?答案是肯定的,那就是MongoDB Database Prof ...

  7. qtp重定义数组大小

    a dim arr1() ) a  dim arr() ReDim arr(a) arr arr ) arr For each i in arr     print arr(i) Next

  8. 奇异值分解(SVD)实例,将不重要的特征值改为0,原X基本保持不变

    >> s = rand(5,7) s = 0.4186  0.8381  0.5028 0.1934 0.6979 0.4966 0.6602 0.8462  0.0196  0.7095 ...

  9. HttpApplication 对象的创建过程及HttpModule过滤器的内部实现过程

    最近通过Reflector学习了一下asp.net内部的原理,做做笔记,方便以后查阅. 先看下HttpApplication 对象的创建过程 从IHttpHandler applicationInst ...

  10. python fabric的安装与使用

    背景:fabric主要执行远程的shell命令,包括文件的上传.下载,以及提示用户输入等辅助其它功能. 测试系统:ubuntu16 要求:python //系统有自带,ubuntu16 通常自带pyt ...