Just an Old Puzzle(HDU-6620)
Problem Description
You 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 0Sample Output
Yes
No
题意:t 组样例,每组给出一个 4*4 形式的数字华容道,其中数字 0 代表空格,即可以移动的位置,问能否将其拼好
思路:
首先将每个数字所在的初始位置与最终应该所在的位置进行标记,然后从 1 开始进行遍历,每交换一次就进行记录
由于空白位置的不确定性,因此开始时,统计用的变量应初始化为空白位置的行列数
在交换过程中,可能出现交换一次后有两个数字复位的情况,最后统计出的结果模 2,若模 2 为 0,则说明可以实现,否则不能实现
Source Program
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<unordered_map>
#include<bitset>
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
#define Pair pair<int,int>
LL quickPow(LL a,LL b){ LL res=1; while(b){if(b&1)res*=a; a*=a; b>>=1;} return res; }
LL multMod(LL a,LL b,LL mod){ a%=mod; b%=mod; LL res=0; while(b){if(b&1)res=(res+a)%mod; a=(a<<=1)%mod; b>>=1; } return res%mod;}
LL quickPowMod(LL a, LL b,LL mod){ LL res=1,k=a; while(b){if((b&1))res=multMod(res,k,mod)%mod; k=multMod(k,k,mod)%mod; b>>=1;} return res%mod;}
LL getInv(LL a,LL mod){ return quickPowMod(a,mod-2,mod); }
LL GCD(LL x,LL y){ return !y?x:GCD(y,x%y); }
LL LCM(LL x,LL y){ return x/GCD(x,y)*y; }
const double EPS = 1E-10;
const int MOD = 998244353;
const int N = 200000+5;
const int dx[] = {-1,1,0,0,1,-1,1,1};
const int dy[] = {0,0,-1,1,-1,1,-1,1};
using namespace std;
int a[N];
int main() {
int t;
scanf("%d",&t);
while (t--) {
int res = 0;
for (int i = 1; i <= 16; i++) {
scanf("%d", &a[i]);
if (a[i] == 0) {
a[i] = 16; //把空白位置记为16号
res = res + (i % 4) + (i / 4);//空白位置
if (i % 4 != 0)
res++;
}
}
for (int i = 1; i <= 16; i++) {
if (a[i] != i) {
res++;
for (int j = 1; j <= 16; j++) {
if (a[j] == i){//交换
swap(a[i],a[j]);
break;
}
}
}
bool flag=false;
for (int j = 1; j <= 16; j++) //每次交换完要判断
if (a[j] != j)
flag= true;
if (!flag) {
if (res % 2 == 0)
printf("Yes\n");
else
printf("No\n");
break;
}
}
}
return 0;
}