hdu6620 Just an Old Puzzle

题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=6620

题目描述

ou are given a 4 × 4 grid, which consists of 15 number cells and an empty cell.
All numbers are unique and ranged from 1 to 15.
In this board, the cells which are adjacent with the empty cell can move to the empty cell.
Your task is to make the input grid to the target grid shown in the figure below.
In the following example (sample input), you can get the target grid in two moves.

 

Input

The first line contains an integer T (1 <= T <= 10^5) denoting the number of test cases.
Each test case consists of four lines each containing four space-separated integers, denoting the input grid. 0 indicates the empty cell.

Output

For each test case, you have to print the answer in one line.
If you can’t get the target grid within 120 moves, then print 'No', else print 'Yes'.

输入输出样例

Sample Input

2

1 2 3 4

5 6 7 8

9 10 0 12

13 14 11 15

1 2 3 4

5 6 7 8

9 10 11 12

13 15 14 0

Sample Output

Yes

No

题意

八数码问题的变形,只不过格子是4*4的。

输入一个数字网格,让你判断可否在120步内将网格的数字移动成为目标网格。

题目理解

题目不会做,看的别人的思路。

网格有解(即将当前网格移动到目标网格)满足以下性质:

1.如果该网格有解,那么它完全可以在80步之内移动到目标网格。所以题目可以转化为判断网格是否有解。

2.若格子列数为奇数,则逆序数必须为偶数。

3.若格子列数为偶数,且逆序数为偶数,则当前空格所在行数与初始空格所在行数的差为偶数。

4.若格子列数为偶数,且逆序数为奇数,则当前空格所在行数与初始空格所在行数的差为奇数。

(逆序数即4*4网格展开后所得序列的逆序数,比如目标网格展开后的序列为1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0)

从初始网格到目标网格,都是那个空白格子不断移动的结果。空白格子左右移动不影响序列逆序数的奇偶,对于上下移动,如果格子列数为奇数,逆序数奇偶不变,如果格子列数为偶数,逆序数奇偶反转(验证一下)。而由于目标网格的逆序数为偶数,且网格列数为4,是偶数,那么我们可以将性质3、4作为依据,判断初始网络是否有解了。

疑点

事实上,我们只能说明只要有解,就一定满足性质3、4,但我们还不能说明满足性质3、4就一定有解,充要性并未得证。另外,关于性质1为何正确我也不明白。欢迎大佬留言指教,多谢!

代码

#include <bits/stdc++.h>
using namespace std;
int a[20];
int main(){
	int i,j,t,pos;
	cin>>t;
	while(t--){
		int ans=0;
		for(i=1;i<=16;i++){
			scanf("%d",&a[i]);
			if(a[i]==0){
				pos=i/4+(i%4!=0); //空位的行数 
			}
			else{                 //求逆序数
				for(j=1;j<i;j++){
					if(a[j]==0)continue;
					if(a[j]>a[i])ans++;
				}
			}
			
		}
		if((4-pos)%2==ans%2){
			cout<<"Yes"<<endl;
		}
		else{
			cout<<"No"<<endl;
		}
	}
	return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值