标签:
给出一个16个点所构成的图形,分别由0,1组成,每次操作可以任选其中相连的两个点(必须一个为0,一个为1),进行0,1,交换
问3步内是否可以把图形变成:0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1状态
若不行,输出more
状压存储图形状态。ida*搜索 或者 BFS都行
IDA*搜索
#include "stdio.h" #include "string.h" const int b[]={0,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536}; const int adj[17][5]= { {0,0,0,0,0}, {0,2,3,5,9}, //1 {0,1,4,6,10}, //2 {0,1,4,7,11}, //3 {0,2,3,8,12}, //4 {0,1,6,7,13}, //5 {0,2,5,8,14}, //6 {0,3,5,8,15}, //7 {0,4,6,7,16}, //8 {0,1,10,11,13}, //9 {0,2,9,12,14}, //10 {0,3,9,12,15}, //11 {0,4,10,11,16}, //12 {0,5,9,14,15}, //13 {0,6,10,13,16}, //14 {0,7,11,13,16}, //15 {0,8,12,14,15} //16 }; int ans,flag,aim; int mark[70010]; int cal(int x) { int i,cnt; cnt=0; for (i=1;i<=8;i++) if ((x&b[i])!=0) cnt++; return cnt; } void dfs(int cur,int n) { int next,x,cnt,i,j; if (cur==aim) { flag=1; return ; } if (flag==1) return ; cnt=0; for (i=1;i<=8;i++) if ((cur&b[i])!=0) cnt++; if (n+cnt>ans) return ; for (i=1;i<=16;i++) { x=cur&b[i]; if (x!=0) for (j=1;j<=4;j++) { x=cur&b[adj[i][j]]; if (x==0) { next=cur; next^=b[i]; next^=b[adj[i][j]]; if (mark[next]==0) { mark[next]=1; dfs(next,n+1); mark[next]=0; } } } } } int main() { int t,Case,i,status,cnt,x; scanf("%d",&t); Case=1; memset(mark,0,sizeof(mark)); while (t--) { status=aim=cnt=0; for (i=1;i<=16;i++) { scanf("%d",&x); if (i<=8) cnt+=x; status+=x*b[i]; } for (i=9;i<=16;i++) aim+=b[i]; printf("Case #%d: ",Case++); if (aim==status) { printf("0\n"); continue; } if (cnt>3) { printf("more\n"); continue; } ans=0; while(1) { ans++; flag=0; if (ans==4) break; mark[status]=1; dfs(status,0); mark[status]=0; if (flag==1) break; } if (ans==4) printf("more\n"); else printf("%d\n",ans); } return 0; }
BFS
#include "stdio.h" #include "string.h" #include "queue" using namespace std; const int b[]={0,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536}; const int adj[17][5]= { {0,0,0,0,0}, {0,2,3,5,9}, //1 {0,1,4,6,10}, //2 {0,1,4,7,11}, //3 {0,2,3,8,12}, //4 {0,1,6,7,13}, //5 {0,2,5,8,14}, //6 {0,3,5,8,15}, //7 {0,4,6,7,16}, //8 {0,1,10,11,13}, //9 {0,2,9,12,14}, //10 {0,3,9,12,15}, //11 {0,4,10,11,16}, //12 {0,5,9,14,15}, //13 {0,6,10,13,16}, //14 {0,7,11,13,16}, //15 {0,8,12,14,15} //16 }; int ans,flag,aim; int mark[70010]; int cal(int x) { int i,cnt; cnt=0; for (i=1;i<=8;i++) if ((x&b[i])!=0) cnt++; return cnt; } int bfs(int cur) { int i,j,next; queue<int>q; q.push(cur); memset(mark,-1,sizeof(mark)); mark[cur]=0; while (!q.empty()) { cur=q.front(); q.pop(); if (mark[cur]==3) continue; for (i=1;i<=16;i++) if ((cur&b[i])!=0) for (j=1;j<=4;j++) if ((cur&b[adj[i][j]])==0) { next=cur; next^=b[i]; next^=b[adj[i][j]]; if (mark[next]==-1 && cal(next)+mark[cur]<=3) { mark[next]=mark[cur]+1; if (next==aim) return mark[next]; q.push(next); } } } return -1; } int main() { int t,Case,i,status,cnt,x; scanf("%d",&t); Case=1; aim=0; for (i=9;i<=16;i++) aim+=b[i]; while (t--) { status=cnt=0; for (i=1;i<=16;i++) { scanf("%d",&x); if (i<=8) cnt+=x; status+=x*b[i]; } printf("Case #%d: ",Case++); if (aim==status) { printf("0\n"); continue; } if (cnt>3) { printf("more\n"); continue; } ans=bfs(status); if (ans==-1) printf("more\n"); else printf("%d\n",ans); } return 0; }
标签:
原文地址:http://blog.csdn.net/u011932355/article/details/45076889