【题解】poj2893 M × N Puzzle 树状数组
学习了大佬博客
#include<cstdio>
#include<cstring>
const int N=1e6+10;
int b[N],a[N],k,n,m,step,s,cnt;
void add(int x)
{
for(;x<=k;x+=x&-x)
b[x]++;
}
int ask(int x)
{
int ans=0;
for(;x>0;x-=x&-x)
ans+=b[x];
return ans;
}
int cal()
{
int i,res=0;
for(i=0;i<k;++i)
{
add(a[i]);
res+=i+1-ask(a[i]);
}
return res;
}
int main()
{
//freopen("in.txt","r",stdin);
int n,m,cnt,step,i,j,s;
while(scanf("%d%d",&m,&n)&&m&&n)
{
memset(b,0,sizeof(b));
k=0;
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
{
scanf("%d",&s);
if(s==0)
step=m-i-1;
else
a[k++]=s;
}
cnt=cal();
if(n&1)
step=0;
printf(step%2==cnt%2?"YES\n":"NO\n");
}
return 0;
}
总结
n*m 数码的有解性判定可以转化为求逆序对来解决。