题目 1426: [蓝桥杯][历届试题]九宫重排

题目链接:https://www.dotcpp.com/oj/problem1426.html

如下面第一个图的九宫格中,放着  1~8  的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。

 

我们把第一个图的局面记为:12345678.
把第二个图的局面记为:123.46758
显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。

输入

输入第一行包含九宫的初态,第二行包含九宫的终态。 

输出

输出最少的步数,如果不存在方案,则输出-1。

样例输入

12345678. 
123.46758 

样例输出

3

超时的一晚,思路都对,就是超时,心态炸了。(记录一下这个题吧)

思路:bfs进行搜,用set<string>来标记。900多ms,差点就超时。

AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#define cla(a, sum) memset(a, sum, sizeof(a))
#define rap(i, m, n) for(i=m; i<=n; i++)
#define rep(i, m, n) for(i=m; i>=n; i--)
#define cl(k) ((k)<<1)
#define cr(k) ((k)<<1|1)
#define bug printf("???\n")
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;
const int Inf = 0x3f3f3f3f;
const double eps = 1e-8;
const int maxn = 3e4;

struct N{
    string s;
    int c;
    N(){};
    N(string s1,int c1):s(s1),c(c1){}
};
int nex[4][2]={0,1,1,0,0,-1,-1,0};

bool judge(int x,int y){
    return 0<=x&&x<=2 && 0<=y&&y<=2;
}
int main()
{
    string be, ed;
    cin>>be>>ed;
    queue<N>que;
    set<string>vis;//标记
    que.push(N(be, 0));
    int ans=-1;
    while(!que.empty()){
        N tmp=que.front(); que.pop();
        if(tmp.s==ed){
            ans = tmp.c;
            break;
        }
        int x=tmp.s.find('.');
        int i=x/3, j=x%3;
        for(int k=0; k<4; k++){
            int i0=i + nex[k][0];
            int j0=j + nex[k][1];
            int x0=i0*3 + j0;
            if(!judge(i0,j0)) continue;
            swap(tmp.s[x], tmp.s[x0]);
            if(!vis.count(tmp.s)){
                vis.insert(tmp.s);
                que.push(N(tmp.s, tmp.c+1));
            }
            swap(tmp.s[x], tmp.s[x0]);
        }
    }
    printf("%d\n",ans);
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值