好题,6666

转自:http://www.cnblogs.com/kuangbin/archive/2012/08/23/2652410.html

题意:给出一个board,上面有24个位置,其中23个位置上放置了标有数字1~23的方块,一个为空位(用数字0表示),现在可以把空位与它旁边的方块交换,给出board的起始状态,问是否可以达到指定的状态。

思路:看起来很像著名的“八数码”问题,首先,针对八个特殊位置(死角),如果这里有空位就把它和相邻的位置交换,这样之后如果两个状态的对应死角上的数字不同,那么显然是不能达到指定状态的,因为无法把死角处的数字换出去。

搞定了死角后就只剩下4×4的board了,这就变成了八数码问题的拓展——15数码。首先想想八数码是如何判断有解的:首先把所有数字(不包括空
位的0)写成一行,就得到了一个1~8的排列,考虑空位的交换情况:1.左右交换,2.上下交换。对于左右交换而言,是不会改变写出的排列的逆序数的;而
对上下交换,相当于在排列中向前或向后跳了两个位置,那么要么两个数都比它大或小,这样逆序数加2或减2,要么两个数一个比它大一个比它小,这样逆序数不
变,综上,对于八数码问题,操作不会改变逆序数的奇偶性,所以只有初始状态和指定状态的逆序数奇偶性相同就有解。

弄清楚了八数码,扩展起来就容易了,现在我们将其扩展到N维(即N*N的board,N*N-1数码问题)。

首先无论N的奇偶,左右交换不改变逆序数,N为奇数时:上下交换逆序数增加N-1或减少N-1或不变,因为N为奇数,所以逆序数奇偶性不变;而N为偶数时:上下交换一次奇偶性改变一次。

结论:N为奇数时,初始状态与指定状态逆序数奇偶性相同即有解;N为偶数时,先计算出从初始状态到指定状态,空位要移动的行数m,如果初始状态的逆序数加上m与指定状态的逆序数奇偶性相同,则有解。

好了,现在这道题就简单了,计算逆序数和空格要移动的行数即可。

 #include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int a[];
int b[];
int c[];
int d[];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
for(int i=;i<;i++)
scanf("%d",&a[i]);
for(int i=;i<;i++)
scanf("%d",&b[i]);
//将八个死角的空转过来
if(a[]==)swap(a[],a[]);
if(a[]==)swap(a[],a[]);
if(a[]==)swap(a[],a[]);
if(a[]==)swap(a[],a[]);
if(a[]==)swap(a[],a[]);
if(a[]==)swap(a[],a[]);
if(a[]==)swap(a[],a[]);
if(a[]==)swap(a[],a[]); if(b[]==)swap(b[],b[]);
if(b[]==)swap(b[],b[]);
if(b[]==)swap(b[],b[]);
if(b[]==)swap(b[],b[]);
if(b[]==)swap(b[],b[]);
if(b[]==)swap(b[],b[]);
if(b[]==)swap(b[],b[]);
if(b[]==)swap(b[],b[]);
bool flag=true;
if(a[]!=b[])flag=false;
if(a[]!=b[])flag=false;
if(a[]!=b[])flag=false;
if(a[]!=b[])flag=false;
if(a[]!=b[])flag=false;
if(a[]!=b[])flag=false;
if(a[]!=b[])flag=false;
if(a[]!=b[])flag=false;
if(flag==false)
{
printf("Y\n");
continue;
}
//转化为n数码问题
for(int i=;i<;i++)
{
c[i]=a[i+];
d[i]=b[i+];
}
for(int i=;i<;i++)
{
c[i]=a[i+];
d[i]=b[i+];
}
for(int i=;i<;i++)
{
c[i]=a[i+];
d[i]=b[i+];
}
//求逆序数
int cnt1=;
int cnt2=;
int m1=,m2=;
for(int i=;i<;i++)
{
if(c[i]==)
{
m1=i;
continue;
}
for(int j=;j<i;j++)
{
if(c[i]<c[j])cnt1++;
}
}
for(int i=;i<;i++)
{
if(d[i]==)
{
m2=i;
continue;
}
for(int j=;j<i;j++)
{
if(d[i]<d[j])cnt2++;
}
}
m1/=;//行数
m2/=;//行数
int m=abs(m1-m2); if(((cnt1+m)%)!=(cnt2%))flag=false;
if(flag)printf("N\n");
else printf("Y\n");
}
return ;
}

hdu 4021 n数码的更多相关文章

  1. Eight POJ - 1077 HDU - 1043 八数码

    Eight POJ - 1077 HDU - 1043 八数码问题.用hash(康托展开)判重 bfs(TLE) #include<cstdio> #include<iostream ...

  2. HDU 1043 八数码(八境界)

    看了这篇博客的讲解,挺不错的.http://www.cnblogs.com/goodness/archive/2010/05/04/1727141.html 判断无解的情况(写完七种境界才发现有直接判 ...

  3. HDU 1043 八数码问题的多种解法

    一.思路很简单,搜索.对于每一种状态,利用康托展开编码成一个整数.于是,状态就可以记忆了. 二.在搜索之前,可以先做个优化,对于逆序数为奇数的序列,一定无解. 三.搜索方法有很多. 1.最普通的:深搜 ...

  4. HDU 1043 八数码(A*搜索)

    在学习八数码A*搜索问题的时候须要知道下面几个点: Hash:利用康托展开进行hash 康托展开主要就是依据一个序列求这个序列是第几大的序列. A*搜索:这里的启示函数就用两点之间的曼哈顿距离进行计算 ...

  5. HDU 1043 八数码 Eight A*算法

    Eight Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  6. Eight hdu 1043 八数码问题 双搜

    Eight Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  7. hdu 1043 八数码问题

    Eight Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  8. hdu 4021 24 Puzzle ( 逆序数判断是否可解 )

    24 Puzzle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others) Total ...

  9. 逆向bfs搜索打表+康拓判重

    HDU 1043八数码问题 八数码,就是1~8加上一个空格的九宫格,这道题以及这个游戏的目标就是把九宫格还原到从左到右从上到下是1~8然后最后是空格. 没了解康托展开之前,这道题怎么想都觉得很棘手,直 ...

随机推荐

  1. Sencha Touch 2.2.1 Custom Icon 自定义图标

    ST2.2版本竟然又改变了sass中自定义图标的添加方式,在2.2以前采用的是这种base64的方式,详见:http://www.cnblogs.com/qidian10/archive/2012/1 ...

  2. WebSphere SSLC0008E 无法初始化 SSL 连接。未授权访问被拒绝,或者安全性设置已到期 解决方法

    昨天安装websphere服务器中间件,安装完毕之后,安装验证如下: 猜测是SSL协议版本过低的问题,于是打开IE高级设置: 勾线之后,启动管理控制台: 成功启动web界面如下: 登陆试试:

  3. windows2008R2安全加固

    一.更改终端默认端口号 步骤: 1.运行regedit 2.[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\W ...

  4. background总结

    1. background-position background-position的百分比属性规则是:图片本身(x%,y%)的那个点,与背景区域的(x%,y%)的那个点重合. 具体可参考: http ...

  5. sql拷贝表结构不拷贝表数据

  6. quick cocos 的scheduler 定时器

    cocos2dx原生lua对于定时器的写法: 1.每帧调用: void scheduleUpdateWithPriority(int priority) void scheduleUpdateWith ...

  7. PHP error_log() 函数

    定义和用法 error_log() 函数向服务器错误记录.文件或远程目标发送一个错误. 若成功,返回 true,否则返回 false. 语法 error_log(error,type,destinat ...

  8. iOS UILabel圆角

    对于UIView 直接设置 uiview.layer.cornerRadius = 5 就可以有圆角了 但是对于UILabel则不然, 要多设置一个uilabel.clipsToBounds = YE ...

  9. lucene搜索方式(query类型)

    Lucene有多种搜索方式,可以根据需要选择不同的方式. 1.词条搜索(单个关键字查找) 主要对象是TermQuery 调用方式如下: Term term=new Term(字段名,搜索关键字);Qu ...

  10. luarocks install with lua5.1 and luajit to install lapis

    # in luarocks source directory...git clone https://github.com/archoncap/luarockscd luarocks ./config ...