两个知识点:
1.15数码若可以解决最坏的情况为移动80次
2.若n为偶数,移动一次(上下移动)空白格 改变的的逆序对为奇数(n-1),左右移动不会改变逆序对,我们的目标是使逆序对为0,并且空白格要在右下角, 那么因为每次空白格移动都会改变奇数的逆序对,那么也就是说移动偶数次0则改变偶数个逆序对,移动奇数次就改变奇数个逆序对,那么若当前的空白格的行数与目标空白格的行数的差(因为只有上下移动才会改变逆序对)若是与当前逆序对的数量的奇偶性相同,那么就一定存在一种方法能够是当前的局达到目标的局,并且零出现在目标空白格位置。
#include <stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int a[20];
int main(int argc, char *argv[])
{
int t;
scanf("%d",&t);
while(t--)
{
int j,i;
int r=0,z=0;
for(i=1;i<=16;i++)
{
scanf("%d",&a[i]);
if(!a[i])z=i/4+(i%4!=0);
else
{
for(j=1;j<i;j++)
{
if(a[j]>a[i])r++;
}
}
}
if((4-z)%2==(r%2))printf("Yes\n");
else printf("No\n");
}
return 0;
}