题目链接: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); }