棋盘游戏
棋盘游戏
题目描述
在一个4*4的棋盘上有8个黑棋和8个白棋,当且仅当两个格子有公共边,这两个格子上的棋是相邻的。移动棋子的规则是交换相邻两个棋子。现在给出一个初始棋盘和一个最终棋盘,要求你找出一个最短的移动序列使初始棋盘变为最终棋盘。
Klux说:“这么简单的题目,我都会做!”
Klux说:“这么简单的题目,我都会做!”
输入
第1到4行每行四个数字(1或者0),描述了初始棋盘
接着是一个空行
第6到9行每行四个数字,描述了最终棋盘
接着是一个空行
第6到9行每行四个数字,描述了最终棋盘
输出
第一行是一个整数n,表示最少的移动步数。
接下来n行每行4个数,r1,c1,r2,c2,表示移动的两个棋子的坐标(r1,c1),(r2,c2)(棋盘左上角的坐标为(1,1),并且他右边的格子为(1,2))
如果有许多组解,你可以输出任意一组。
接下来n行每行4个数,r1,c1,r2,c2,表示移动的两个棋子的坐标(r1,c1),(r2,c2)(棋盘左上角的坐标为(1,1),并且他右边的格子为(1,2))
如果有许多组解,你可以输出任意一组。
样例输入
1111
0000
1110
0010
1010
0101
1010
0101
样例输出
4
1 2 2 2
1 4 2 4
3 2 4 2
4 3 4 4
分析:写成16位的二进制数后宽搜即可;
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <climits> #include <cstring> #include <string> #include <set> #include <map> #include <queue> #include <stack> #include <vector> #include <list> #define rep(i,m,n) for(i=m;i<=n;i++) #define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++) #define mod 1000000007 #define inf 0x3f3f3f3f #define vi vector<int> #define pii pair<int,int> #define pb push_back #define mp make_pair #define fi first #define se second #define ll long long #define pi acos(-1.0) const int maxn=1<<16; const int dis[4][2]={{0,1},{-1,0},{0,-1},{1,0}}; using namespace std; ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);} ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;} int n,m,k,t,vis[maxn],pre[maxn]; struct node { int prex,prey,x,y; }ans[maxn]; queue<int>p; void dfs(int now) { if(ans[pre[now]].x)dfs(pre[now]); printf("%d %d %d %d\n",ans[now].prex,ans[now].prey,ans[now].x,ans[now].y); } int main() { int i,j; rep(i,0,15)scanf("%1d",&j),n+=j*(1<<i); vis[n]=1;p.push(n); rep(i,0,15)scanf("%1d",&j),m+=j*(1<<i); if(n==m)return 0*puts("0"); while(!p.empty()) { int q=p.front();p.pop(); rep(i,0,11) { int u=((q&(1<<i))>>i),v=((q&(1<<i+4))>>(i+4)); if(u!=v) { int r=q+((1<<i+4)-(1<<i))*(u-v); if(!vis[r]) { p.push(r); ans[r].prex=i/4+1; ans[r].prey=i%4+1; ans[r].x=(i+4)/4+1; ans[r].y=(i+4)%4+1; pre[r]=q; vis[r]=vis[q]+1; if(r==m)goto loop; } } } rep(i,0,15) { if(i%4==3)continue; int u=((q&(1<<i))>>i),v=((q&(1<<i+1))>>(i+1)); if(u!=v) { int r=q+((1<<i+1)-(1<<i))*(u-v); if(!vis[r]) { p.push(r); ans[r].prex=i/4+1; ans[r].prey=i%4+1; ans[r].x=(i+1)/4+1; ans[r].y=(i+1)%4+1; pre[r]=q; vis[r]=vis[q]+1; if(r==m)goto loop; } } } } loop:; printf("%d\n",vis[m]-1); dfs(m); //system("pause"); return 0; }