#include<algorithm> #include<cstdio> #include<iostream> #include<queue> #include<cstring> using namespace std; unsigned x; unsigned int goal;//最终状态表示的数值 const int dx[]={0,0,1,-1}; const int dy[]={1,-1,0,0}; int ans = 0; int hash[65535+100]; void print(int a[5][5]); unsigned int num(int a[5][5]); void copy(int b[5][5],int a[5][5]); void num_change(unsigned int x,int a[5][5]); struct Node { Node(int _level,unsigned int _x):level(_level),x(_x){ } int level; unsigned int x; }; int main(void) { cin >> x; int a[5][5]; int mod = 1; for(int i=1;i<=8;i++) { goal += mod; mod*=2; } hash[x]=1; queue<Node>que; Node p = Node(0,x); que.push(p); while(!que.empty()) { Node temp = que.front() ; que.pop(); if(temp.x == goal) { ans = temp.level; break; } int b[5][5],next_level = temp.level+1; //cout << next_level << endl; num_change(temp.x,b); for(int i=1;i<=4;i++) { for(int j=1;j<=4;j++) { if(b[i][j]) { for(int dir=0;dir<4;dir++) { int newx = i+dx[dir]; int newy = j+dy[dir]; if(newx>=1 && newx<=4 && newy>=1 && newy<=4 && b[newx][newy]==0) { int c[5][5]; copy(c,b); c[i][j]=0; c[newx][newy]=1; if(hash[num(c)]==0) { p=Node(next_level,num(c)); que.push(p); hash[num(c)]=1; } } } } } } } cout << ans ; return 0; } void print(int a[5][5]) { for(int i=1;i<=4;i++) { for(int j=1;j<=4;j++) { cout << a[i][j] << " "; } cout << endl; } } unsigned int num(int a[5][5]) { unsigned int q = 1; unsigned int sum = 0; for(int i=4;i>=1;i--) { for(int j=4;j>=1;j--) { sum += a[i][j]*q; q*=2; } } return sum; } void copy(int b[5][5],int a[5][5]) { for(int i=1;i<=4;i++) for(int j=1;j<=4;j++) b[i][j]=a[i][j]; } void num_change(unsigned int x,int a[5][5]) { unsigned int mod = 2; for(int i=4;i>=1;i--) { for(int j=4;j>=1;j--) { a[i][j]=x%2; x/=2; } } }
这是一个通用的方法,还可以使用贪心算法:
可以先将每一列的0全部移动到这一列的上方,然后如果白色的棋子没有刚好形成两行,那么就依次 将移动之后 最下方的白色棋子移动到黑色棋子最高的地方。
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; int ans[5][5]; int main(void) { unsigned int x; cin >> x; int a[5][5]; for(int i=4;i>=1;i--) { for(int j=4;j>=1;j--) { a[i][j]=x%2; x/=2; } } int step = 0; for(int j=1;j<=4;j++) { int sum0=0,pos=0; for(int i=1;i<=4;i++) { if(a[i][j]==0) { sum0++; pos+=i; } } if(sum0==1) step+=pos-1,ans[2][j]=ans[3][j]=ans[4][j]=1; if(sum0==2) step+=pos-1-2,ans[3][j]=ans[4][j]=1; if(sum0==3) step+=pos-1-2-3,ans[4][j]=1; if(sum0==4) step+=pos-1-2-3-4; } bool find = true; while(find) { int x1,y1,x2,y2; find = false; for(int i=4;i>=3;i--) { for(int j=4;j>=1;j--) { if(ans[i][j]==0) { find = true; x1=i,y1=j; break; } } if(find) break; } bool first=false; if(find) { for(int i=1;i<=2;i++) { for(int j=4;j>=1;j--) { if(ans[i][j]==1) { first = true; x2=i,y2=j; break; } } if(first) break; } step+=abs(x1-x2)+abs(y1-y2); ans[x1][y1]=1; ans[x2][y2]=0; } } cout << step; return 0; }