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;
}

 

转载于:https://www.cnblogs.com/nanke/archive/2012/04/13/2445266.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值