题目来源: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. performance.timing检测页面加载速度

    with(performance){ readyStart = timing.fetchStart - timing.navigationStart; redirectTime = timing.re ...

  2. Arc077_E Guruguru

    传送门 题目大意 有$m$个点编号从小到大按照顺时针编成了一个环,有一枚棋子,每次移动可以选择顺时针移动到下一个或者直接移动到编号为$x$的点,现在有$n-1$次数操作,第$i$次要把棋子从第$A_i ...

  3. Agc017_E Jigsaw

    传送门 题目大意 有$n$块拼图,每一块都由左中右三个部分组成,每块拼图中间部分是高为$H$的长方形,对于第$i$块品推左侧是高为$A_i$距离底部为$C_i$的长方体,右侧是高位$B_i$距底部为$ ...

  4. 20179203李鹏举 《Linux内核原理与分析》第一周学习笔记

    Linux基础入门 一.Linux的基础学习 1.1 Linux的重要基础操作 Linux不同于Windows的纯粹的图形化界面,虽然也有图形桌面的操作但是更多的操作还是通过命令行来进行,当然除了命令 ...

  5. sql根据坐标算距离

    CREATE FUNCTION ConvertXYToDistance(@la1 DECIMAL,@lo1 DECIMAL,@la2 DECIMAL,@lo2 DECIMAL)RETURNS FLOA ...

  6. Spring 3.1新特性之四:p命名空间设置注入(待补充)

    https://www.ibm.com/developerworks/cn/java/j-lo-jparelated/ http://www.ibm.com/developerworks/cn/jav ...

  7. JAVA 1.5 局部特性(可变参数/ANNOTATION/并发操作)

    1: 可变参数 可变参数意味着可以对某类型参数进行概括,例如十个INT可以总结为一个INT数组,当然在固定长度情况下用数组是很正常的 这也意味着重点是可变,不定长度的参数 PS1:对于继承和重写我没有 ...

  8. 不支持PowerShell 2.0版本(don't support PowerShell version 2.0. )

    在“程序包管理器控制台”使用命令“update-database”会提示:The Entity Framework Core Package Manager Console Tools don't s ...

  9. .clearfix:after

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. Servlet编程实例 续4

    ---------------siwuxie095 JSP+Servlet+JDBC 继续完善登录实例,将校验逻辑改为:从数据库中获取用户信息进行校验 数据库准备 在 Navicat for MySQ ...