hdu 1043(八数码问题)
来源:互联网 发布:淘宝 开电玩店 编辑:程序博客网 时间:2024/05/16 09:10
<span style="font-family: Arial, Helvetica, sans-serif;">题意:省略</span>
解题思路:针对八数码问题,如果x往左或往右走,是不会改变逆序数大小的,且往上或往下走只有三种情况,讨论往下走,如果与x交换的数是ai,则要判断的是a(i-1),a(i-2)与ai的关系.
只会出现四种情况,a(i-1)>ai,a(i-2)>ai;逆序对数在原来的基础上+2
a(i-1)<ai,a(i-2)>ai;逆序对数在原来的基础上不变
a(i-1)>ai,a(i-2)<ai;逆序对数在原来的基础上不变
a(i-1)<ai,a(i-2)<ai;逆序对数在原来的基础上-2
针对上述四种情况,逆序数的初始值为0,则经过各种变换逆序数为偶数,则若一种状态逆序数为奇数,始不可能的。且在保存状态时利用康托展开:X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0! (ai为某个数对应的逆序对数,达到状态压缩)。
这里要利用反向的思维,通过最终状态去bfs所有状态。
只会出现四种情况,a(i-1)>ai,a(i-2)>ai;逆序对数在原来的基础上+2
a(i-1)<ai,a(i-2)>ai;逆序对数在原来的基础上不变
a(i-1)>ai,a(i-2)<ai;逆序对数在原来的基础上不变
a(i-1)<ai,a(i-2)<ai;逆序对数在原来的基础上-2
针对上述四种情况,逆序数的初始值为0,则经过各种变换逆序数为偶数,则若一种状态逆序数为奇数,始不可能的。且在保存状态时利用康托展开:X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0! (ai为某个数对应的逆序对数,达到状态压缩)。
这里要利用反向的思维,通过最终状态去bfs所有状态。
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <queue>using namespace std;#define MAXN 50#define MAZE 600000typedef struct node{ char str[50]; int nx[9]; int num,hashnum,xind; node(); node(char *ss,int nu,int hanu,int *nnx){ strcpy(str,ss); num = nu; hashnum = hanu; for(int i=0;i<9;++i){ nx[i] = nnx[i]; } } void charstr(){ int tmp = 0; int tmpc; int tmpnum = num; tmpc = 9; int zflag = 0; while(num){ zflag = num%10; str[tmpc -1] = '0'+ zflag; if(zflag==9) tmp = tmpc - 1; num/=10; --tmpc; } num = tmpnum; xind = tmp; //return tmp; }};queue<node>q;int path[MAZE];int nx[9];int pa[MAZE],ans[MAZE];bool vis[MAZE];char nows[MAXN];int cnt;int p[]={1,1,2,6,24,120,720,5040,40320};int pw[] = {100000000,10000000,1000000,100000,10000,1000,100,10,1};int dx[] = {0,0,1,-1};int dy[] = {1,-1,0,0};int goal;void prepro(){ cnt = 0; int len = (int)strlen(nows); for(int i=0;i<len;++i){ if(nows[i]==32)continue; if(nows[i]=='x')nows[i] = '9'; nows[cnt++] = nows[i]; } nows[cnt] = 0;}void init(){ memset(vis,false,sizeof(vis)); memset(pa,-1,sizeof(pa));}int charhash(char *str){ //就保证系数ai》=0&&ai<=(8 - i) int ans = 0,tmpc; int st = 0; for(int i=0;i<cnt;++i){ //if(nows[i]=='x')continue; tmpc = 0; for(int j = i+1;j<cnt;++j){ // if(nows[j]=='x')continue; if(str[i]>str[j])tmpc++; } nx[i] = tmpc; ans+=tmpc*p[8-i]; //st++; } return ans;}int getnx(){ int ans = 0; for(int i=0;i<cnt;++i){ //if(nows[i]=='x')continue; if(nows[i]=='9')continue; for(int j=i+1;j<cnt;++j){ // if(nows[j]=='x')continue; if(nows[i]>nows[j]) ans++; } } return ans;}int getnumber(){ int ans = 123456789; return ans;}//右 左 下 上int gethash(char *str,int num,int dir,int xind,int nxind,node &no){ int tmpcc; if(dir==0){ num = num-p[8-xind]*no.nx[xind] - p[8-nxind]*no.nx[nxind]; tmpcc = no.nx[nxind]; no.nx[nxind]=no.nx[xind] - 1; no.nx[xind] = tmpcc; num+=p[8-xind]*no.nx[xind] + p[8-nxind]*no.nx[nxind]; } if(dir==1){ num = num-p[8-xind]*no.nx[xind] - p[8-nxind]*no.nx[nxind]; tmpcc = no.nx[nxind]; no.nx[nxind]=no.nx[xind] + 1; no.nx[xind] = tmpcc; num+=p[8-xind]*no.nx[xind] + p[8-nxind]*no.nx[nxind]; } if(dir==2){ int ind1,ind2; ind1 = xind+1; ind2 = xind+2; int cc = 0; if(str[nxind]>str[ind1])cc++; if(str[nxind]>str[ind2])cc++; num = num-p[8-xind]*no.nx[xind] - p[8-nxind]*no.nx[nxind]; tmpcc = no.nx[nxind]; no.nx[nxind]=no.nx[xind] - 3; no.nx[xind] = tmpcc+cc; num+=p[8-xind]*no.nx[xind] + p[8-nxind]*no.nx[nxind]; if(str[nxind]<str[ind1]){ num-=p[8-ind1]; no.nx[ind1]--; } if(str[nxind]<str[ind2]){ num-=p[8-ind2]; no.nx[ind2]--; } } if(dir==3){ int ind1,ind2; ind1 = xind-1; ind2 = xind-2; int cc = 0; if(str[nxind]>str[ind1])cc++; if(str[nxind]>str[ind2])cc++; num = num-p[8-xind]*no.nx[xind] - p[8-nxind]*no.nx[nxind]; tmpcc = no.nx[nxind]; no.nx[nxind]=no.nx[xind] + 3; no.nx[xind] = tmpcc-cc; num+=p[8-xind]*no.nx[xind] + p[8-nxind]*no.nx[nxind]; if(str[nxind]<str[ind1]){ num+=p[8-ind1]; no.nx[ind1]++; } if(str[nxind]<str[ind2]){ num+=p[8-ind2]; no.nx[ind2]++; } } return num;}//右 左 下 上void restart(char *str,int num,int dir,int xind,int nxind,node &no){ int tmpcc; if(dir==0){ // num = num-p[8-xind]*no.nx[xind] - p[8-nxind]*no.nx[nxind] + p[8-xind]*(no.nx[nxind]-1) + p[8-nxind]*no.nx[xind]; tmpcc = no.nx[xind]; no.nx[xind]=no.nx[nxind] + 1; no.nx[nxind] = tmpcc; } if(dir==1){ // num = num-p[8-xind]*no.nx[xind] - p[8-nxind]*no.nx[nxind] + p[8-xind]*(no.nx[nxind]+1) + p[8-nxind]*no.nx[xind]; tmpcc = no.nx[xind]; no.nx[xind]=no.nx[nxind] - 1; no.nx[nxind] = tmpcc; } if(dir==2){ int ind1,ind2; ind1 = xind+1; ind2 = xind+2; int cc = 0; if(str[nxind]>str[ind1])cc++; if(str[nxind]>str[ind2])cc++; // num = num-p[8-xind]*no.nx[xind] - p[8-nxind]*no.nx[nxind] + p[8-xind]*(no.nx[nxind]-2) + p[8-nxind]*(no.nx[xind]+cc); tmpcc = no.nx[xind]; no.nx[xind]=no.nx[nxind] + 3; no.nx[nxind] = tmpcc-cc; if(str[nxind]<str[ind1]){ // num+=p[8-ind1]; no.nx[ind1]++; } if(str[nxind]<str[ind2]){ //num+=p[8-ind2]; no.nx[ind2]++; } } if(dir==3){ // num = num-p[8-xind]*no.nx[xind] - p[8-nxind]*no.nx[nxind] + p[8-xind]*(no.nx[nxind]+2) + p[8-nxind]*(no.nx[xind]-cc); int ind1,ind2; ind1 = xind-1; ind2 = xind-2; int cc = 0; if(str[nxind]>str[ind1])cc++; if(str[nxind]>str[ind2])cc++; tmpcc = no.nx[xind]; no.nx[xind]=no.nx[nxind] - 3; no.nx[nxind] = tmpcc+cc; if(str[nxind]<str[ind1]){ //num-=p[8-ind1]; no.nx[ind1]--; } if(str[nxind]<str[ind2]){ //num=p[8-ind2]; no.nx[ind2]--; } } // return num;}void solve(){ //int front,rear; // if(getnx()&1) // return false; int num = getnumber(); int hashnum; hashnum = charhash("123456789"); node no("123456789",num,hashnum,nx); no.charstr(); q.push(no); //vis[num] = true; int tmpnum,xind,nxind; int x,y,nx,ny; while(!q.empty()){ no = q.front(); q.pop(); // num = no.num; //if(goal==no.hashnum)return true; xind = no.xind; if(vis[no.hashnum])continue; vis[no.hashnum] = true; //xind = charstr(num); x = xind/3; y = xind%3; for(int i=0;i<4;++i){//右 左 下 上 nx = x + dx[i]; ny = y + dy[i]; if(nx>=0&&nx<3&&ny>=0&&ny<3){ nxind = nx*3+ny; tmpnum = gethash(no.str,no.hashnum,i,xind,nxind,no); int cc = no.str[nxind] - '0'; no.str[xind] = no.str[nxind]; no.str[nxind] = '9'; // int chc = charhash(no.str); int t1,t2; // t1 = no.num; t2 = no.hashnum; if(!vis[tmpnum]){ pa[tmpnum] = no.hashnum; path[tmpnum] = i; // int tmpcc = num + (9 - cc)*(pw[nxind]-pw[xind]); // no.num = tmpcc; no.hashnum = tmpnum; no.xind = nxind; q.push(no); } no.str[nxind] = no.str[xind]; no.str[xind] = '9'; // no.num = t1; no.hashnum = t2; no.xind = xind; restart(no.str,no.hashnum,i,xind,nxind,no); } } } // return false;}int getdir(int num){ switch(num){ case 0: return 'l'; case 1: return 'r'; case 2: return 'u'; case 3: return 'd'; } return 0;}void output(bool flag,int hashnum){ if(!flag){ printf("unsolvable\n"); return; } int cntans = 0; int tmp = hashnum; //char ss[]="ullddrurdllurdruldr"; //printf("%d\n",strlen(ss)); while(1){ if(pa[tmp]==-1)break; ans[cntans++] = path[tmp]; tmp = pa[tmp]; } //printf("%d",ans[0]); // printf("%d\n",cntans); for(int i=0;i<cntans;++i){ putchar(getdir(ans[i])); } printf("\n");}void clear(){ while(!q.empty()){ q.pop(); }}int main(){ init(); goal = 0; solve(); //clear(); bool flag; while(gets(nows)){ flag = true; prepro(); int hashnum = charhash(nows); if(!vis[hashnum])flag = false; output(flag,hashnum); } return 0;}
- hdu 1043(八数码问题)
- HDU:1043 八数码问题
- hdu 1043 eight 八数码问题
- HDU 1043 八数码问题 A*搜索
- 八数码问题(HDU 1043)
- HDU-1043 Eight 八数码问题
- HDU 1043 八数码问题 A*搜索
- 八数码问题——HDU 1043
- hdu 1043 八数码问题-A*搜索
- HDU 1043(八数码问题)
- hdu 1043 Eight 经典八数码问题
- HDU 1043 八数码
- HDU 1043 eight 八数码
- HDU-1043-八数码-代码
- 八数码(hdu 1043)
- hdu 1043 八数码 A*
- 八数码--HDU - 1043 Eight
- HDU 1043 Eight 八数码
- 锚文字切忌画蛇添足
- javaEE设计思想和技术架构
- StatSVN(查看NVS用户修改代码的情况)
- ios中的initWithFrame
- html条件注释代码
- hdu 1043(八数码问题)
- JPA的persistence.xml配置文件参数
- 单片机软件设计思路
- ITween函数总结(一)
- linux目录下的一级子目录过多,导致创建目录失败(java file mkdirs)
- linux字符串的处理
- 类别在ios中的使用
- 移动 view 的位置
- NVS计统工具statnvs