The Eight Puzzle, among other sliding-tile puzzles, is one of the famous problems in artificial intelligence. Along with chess, tic-tac-toe and backgammon, it has been used to study search algorithms.

The Eight Puzzle can be generalized into an M × N Puzzle where at least one of M and N is odd. The puzzle is constructed with MN − 1 sliding tiles with each a number from 1 to MN − 1 on it packed into a M by N frame with one tile missing. For example, with M = 4 and N = 3, a puzzle may look like:

1 6 2
4 0 3
7 5 9
10 8 11

Let's call missing tile 0. The only legal operation is to exchange 0 and the tile with which it shares an edge. The goal of the puzzle is to find a sequence of legal operations that makes it look like:

1 2 3
4 5 6
7 8 9
10 11 0

The following steps solve the puzzle given above.

START

1 6 2
4 0 3
7 5 9
10 8 11

DOWN

1 0 2
4 6 3
7 5 9
10 8 11
LEFT
1 2 0
4 6 3
7 5 9
10 8 11

UP

1 2 3
4 6 0
7 5 9
10 8 11

 

RIGHT

1 2 3
4 0 6
7 5 9
10 8 11

UP

1 2 3
4 5 6
7 0 9
10 8 11
UP
1 2 3
4 5 6
7 8 9
10 0 11

LEFT

1 2 3
4 5 6
7 8 9
10 11 0

GOAL

Given an M × N puzzle, you are to determine whether it can be solved.

Input

The input consists of multiple test cases. Each test case starts with a line containing M and N (2 ≤ M, N ≤ 999). This line is followed by M lines containing N numbers each describing an M × N puzzle.

The input ends with a pair of zeroes which should not be processed.

Output

Output one line for each test case containing a single word YES if the puzzle can be solved and NO otherwise.

Sample Input

3 3
1 0 3
4 2 5
7 8 6
4 3
1 2 5
4 6 9
11 8 10
3 7 0
0 0

Sample Output

YES
NO 题意:给你一个m*n的矩阵,0代表空,0位置可以和上下左右位置交换,问是否可以变成1~m*n-1顺序排列且0在第m*n的位置的图,看上面例子。
思路:这就是一个奇数码问题的扩展,我们将其看成一条链,将0去除。
①对于n的奇数码问题,我们知道若能从一个图转换成另一张图,只需要比较两个图的逆序对奇偶性是否相同即可。(上下交换,交换n-1个数,n-1为偶数,不影响逆序对奇偶性)
②对于n的偶数码问题,我们左右交换依然不增减逆序对,但是上下交换,将交换n-1个数,n-1为奇数,将改变逆序对奇偶性,我们需要判断 【一个图的逆序对+空位置行的差值】与【另一图的逆序对】
 #include<cstdio>
#include<iostream> using namespace std; const int maxn = 1e6+;
int a[maxn];
typedef long long ll;
int Mergesort(int l,int r)
{
int mid = (l+r)/;
int b[r-l+];
int i=l,j=mid+;
int m=;
int cnt = ;
while(i <= mid && j <= r)
{
if(a[i] > a[j])
b[m++] = a[j++],cnt += mid-i+;
else
b[m++] = a[i++];
}
while(i <= mid)
{
b[m++] = a[i++];
}
while(j <= r)
{
b[m++] = a[j++];
}
m = ;
for(int i=l; i<=r; i++)
{
a[i] = b[m++];
}
return cnt;
} void Merge(int l,int r,ll& ans)
{
if(l >= r)
return;
int mid = (l+r)/;
Merge(l,mid,ans);
Merge(mid+,r,ans);
ans += Mergesort(l,r);
}
int n,m;
int main()
{
while(~scanf("%d%d",&n,&m)&&n&&m)
{
int tmp;
int cnt = ;
int row;
for(int i=; i<=n; i++)
{
for(int j=; j<=m; j++)
{
scanf("%d",&tmp);
if(tmp)
a[cnt++] = tmp;
else row = i;
}
}
ll ans = ;
Merge(,cnt-,ans);
int flag = ;
if(m&){if((ans & ) == )flag = ;}
else if((ans+n-row) % == )flag = ;
if(flag)printf("YES\n");
else printf("NO\n");
}
}
												

M × N Puzzle POJ - 2893(奇数码)的更多相关文章

  1. CH Round #72 奇数码问题[逆序对 观察]

    描述 你一定玩过八数码游戏,它实际上是在一个3*3的网格中进行的,1个空格和1~8这8个数字恰好不重不漏地分布在这3*3的网格中. 例如:5 2 81 3 _4 6 7 在游戏过程中,可以把空格与其上 ...

  2. poj2893 M*N puzzle 【n*m数码问题小结】By cellur925

    题目传送门 这个问题是来源于lydrainbowcat老师书上讲排序的一个扩展.当时讲的是奇数码问题,其实这种问题有两种问法:一种局面能否到另一种局面.到达目标局面的最小步数. 本文部分内容引用于ly ...

  3. AcWing:108. 奇数码问题(归并排序 + 逆序数)

    你一定玩过八数码游戏,它实际上是在一个3×3的网格中进行的,1个空格和1~8这8个数字恰好不重不漏地分布在这3×3的网格中. 例如: 5 2 8 1 3 _ 4 6 7 在游戏过程中,可以把空格与其上 ...

  4. 区间dp E - Multiplication Puzzle POJ - 1651

    E - Multiplication Puzzle  POJ - 1651 这个题目没有特别简单,但是也没有我想象之中的那么难,这个题目时区间dp,因为我们是要对区间进行考虑的. 但是呢,这个也和动态 ...

  5. POJ 2893 M × N Puzzle——八数码有解条件

    题意:给定M*N的数码图,问能否移动到最终状态 分析 有解的判定条件可见 八数码有解条件 值得一提的是,这道题求逆序对卡树状数组,只能用归并排序. #include<cstdio> #in ...

  6. POJ 2893 M × N Puzzle(树状数组求逆序对)

                                                               M × N Puzzle Time Limit: 4000MS   Memory ...

  7. POJ 2893 M × N Puzzle

    逆序对 n 数码问题的扩展 对于一个n * m 的问题来说,结论和 列数 m 奇偶有关 对于 m 是奇数来说 , 两个局面互相可达,当且仅当这两个局面按顺序写成一个数列,这个数列的逆序对数的奇偶性相同 ...

  8. HDU 3600 Simple Puzzle 归并排序 N*N数码问题

    先介绍八数码问题: 我们首先从经典的八数码问题入手,即对于八数码问题的任意一个排列是否有解?有解的条件是什么? 我在网上搜了半天,找到一个十分简洁的结论.八数码问题原始状态如下: 1 2 3 4 5 ...

  9. poj 1077-Eight(八数码+逆向bfs打表)

    The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've see ...

随机推荐

  1. Centos7 linux 卸载自带安装的jdk 并yum自动安装jdk1.8

    一:卸载系统自带安装的JDK 注:本文参考了< 使用CentOS7卸载自带jdk安装自己的JDK1.8> 通过xshell工具成功连接安装好的虚拟机之后可通过    rpm -qa | g ...

  2. Confluence 6 配置索引语言

    修改你 Confluence 的索引语言将有助于你提高搜索的准确性,如果你网站使用的主要语言是除了英语以外的其他语言. Confluence 可以支持下面语言的的内容索引: Arabic Brazil ...

  3. Confluence 6 配置管理员联系页面

    管理员联系页面是一个格式化的页面,这个页面能够允许 Confluence 用户在 Confluence 中向管理员发送消息(在这部分的内容,管理员是默认管理员用户组的成员). 有关用户组的解释,请参考 ...

  4. 第二十单元 计划任务crond服务

    什么是计划任务:后台运行,到了预定的时间就会自动执行的任务,前提是:事先手动将计划任务设定好.这就用到了crond服务 crond服务相关的软件包[root@MiWiFi-R3-srv ~]# rpm ...

  5. mac 显示/不显示"任何来源"_ mac打开安装文件显示文件破损解决办法

    系统: macOS_10.12 导致文件破损原因: 软件有经过了汉化或者破解,所以可能被Mac认为「已损坏」 解决问题办法: 系统偏好设置 -> 安全性与隐私 -> 通用 -> 选择 ...

  6. jmeter 控制线程组执行顺序

    这个要配合全局变量.if和while来实现BeanShell取样器,全局变量:${__setProperty(newswitch,${switch1},)}if条件:"${__P(newsw ...

  7. Jmeter BeanShell PostProcessor提取json数据

    需求:提取sample返回json数据中所有name字段值,返回的json格式如下: {“body”:{“apps”:[{“name”:”111”},{“name”:”222”}]}} jmeter中 ...

  8. AI学习吧-登录注册

    登录注册注销 如果需要给表设置权限,没有登录就不可以查看,只需要在每个视图函数之前加上Auth_classes=[ ]即可! 增加两张表,做登录认证 #models.py #做登录验证 class U ...

  9. C++ Primer 笔记——基本内置类型

    1.算术类型分为两类:整型和浮点型.算术类型的尺寸在不同机器上有所差别,下表列出了C++标准规定的尺寸的最小值.同时允许编译器赋予这些类型更大的尺寸. 一个char的大小和一个机器字节一样. 一个in ...

  10. 俺也会刷机啦--windows7下刷android

    刷机很多人都会,本文只为像我这种入门的朋友而写的. 风险提示: 1. SD卡数据极可能会丢失(我这次就全丢了). 2. 升级失败. (俺的)环境说明: windows7 专业版64位 cmd命令行工具 ...