棋盘游戏

棋盘游戏

题目描述

在一个4*4的棋盘上有8个黑棋和8个白棋,当且仅当两个格子有公共边,这两个格子上的棋是相邻的。移动棋子的规则是交换相邻两个棋子。现在给出一个初始棋盘和一个最终棋盘,要求你找出一个最短的移动序列使初始棋盘变为最终棋盘。
Klux说:“这么简单的题目,我都会做!”

输入

第1到4行每行四个数字(1或者0),描述了初始棋盘
接着是一个空行
第6到9行每行四个数字,描述了最终棋盘

输出

第一行是一个整数n,表示最少的移动步数。
接下来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
",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
",vis[m]-1);
    dfs(m);
    //system("pause");
    return 0;
}
原文地址:https://www.cnblogs.com/dyzll/p/5779613.html