Time limit 2000 ms
Memory limit 262144 kB
OS Windows
解题过程
感觉搜索不可行,状态太多了,120步,判断状态是否重复时,即使用std::map
也太慢了点。然后不会了。之后百度了一下
原来这个叫15数码问题啊……(另外,以后写博客有没有必要在底部搞个正经的参考文献列表呢?带格式的那种)
结论如下——首先记录0所在的行数。然后把这四行排成一排,去掉0,求一次逆序对数。有解的充要条件是,0所在行数和排成一排的逆序数奇偶性相同。另外,大胆猜测,不会证明,有解就一定可以在120步之内求出来。然后没了。
源代码
#include<stdio.h>
int T;
int a[20],zero_raw;
int calc()//暴力求逆序对
{
int ans=0;
for(int i=1;i<16;i++)
{
if(a[i]==0) continue;
for(int j=i+1;j<=16;j++)
{
if(a[j]==0) continue;
if(a[j]<a[i]) ans++;
}
}
return ans;
}
int main()
{
scanf("%d",&T);
while(T--)
{
for(int i=1;i<=4;i++)
{
for(int j=1;j<=4;j++)
{
scanf("%d",a+(i-1)*4+j);
if(a[(i-1)*4+j]==0) zero_raw=i;//0所在行数
}
}
int temp=calc()+zero_raw;
if(temp%2==0) puts("Yes");
else puts("No");
}
return 0;
}