hdu 3600 Simple Puzzle (判断N 数码是否有解)

分析:

当N为奇数时奇偶同性可互达,N为偶数时,逆序数之和sum加上空格所在行距目标空格行的距离dis之和要和终点状态逆序数同奇偶

View Code
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
const int N = 300+10;
int s[N*N],g[N*N];
#define _cp(a,b) ((a)<=(b))
int _tmp[N*N];
int inv(int n,int* a){
    int l=n>>1,r=n-l,i,j;
    int ret=(r>1?(inv(l,a)+inv(r,a+l)):0);
    for (i=j=0;i<=l;_tmp[i+j]=a[i],i++)
        for (ret+=j;j<r&&(i==l||!_cp(a[i],a[l+j]));_tmp[i+j]=a[l+j],j++);
    memcpy(a,_tmp,sizeof(int)*n);
    return ret;
}
int main()
{

    int n;
    while(scanf("%d",&n)==1 && n)
    {
        int num=0;
        bool flag=true;
        for(int i=0;i<n*n;i++)
        {
            scanf("%d",&g[i]);
            if(flag && g[i]!=0)
                num++;
            if(g[i]==0)
                flag=false;
        }
        int temp=inv(n*n,g);
        temp-=num;//0的逆序数不考虑
        if(!(n&1))//若n为偶数,则要加上空格所在行距目标空格行的距离dis之和
        temp+=(n-1-(num/n));
        if(temp&1)
            puts("NO");
        else puts("YES");
    }
    return 0;
}

 

posted @ 2012-04-13 09:45  枕边梦  阅读(525)  评论(0编辑  收藏  举报