1 条题解
-
0
自动搬运
来自洛谷,原作者为

hidden_er
**搬运于
2025-08-24 21:24:25,当前版本为作者最后更新于2017-11-01 21:42:52,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
上次发过超长代码的题解后惨遭同校大佬批斗
痛定思痛,在向大佬学习之后,带来最短代码(滑稽)
思路大体与之前相同:
map去重,
在这里只需要一个队列,因为需要较少步数达到的状态一定在步数较多的状态前入队列
(我之前那个最长程序也可以用一个队列,不需要两个队列辗转,只要加个步数的记录就行了)
stl大法好%%%
#include<iostream> #include<map> #include<queue> #include<algorithm> #define ll long long//在这里看到一种很骚的操作:直接把int定义成long long;main函数用signed类型--麻麻再也不怕我忘开long long了! using namespace std; const ll dx[]={-1,0,0,1},dy[]={0,-1,1,0};//转移数组; ll n; int main() { cin>>n; queue<ll> q; q.push(n); map<ll,ll> m; m[n]=0; while(!q.empty()) { int u=q.front(); //初始状态入队列 int c[3][3],f=0,g=0,n=u;q.pop(); if(u==123804765)break; for(ll i=2;i>=0;i--) for(ll j=2;j>=0;j--) { c[i][j]=n%10,n/=10; if(!c[i][j])f=i,g=j; } for(ll i=0;i<4;i++) { ll nx=f+dx[i],ny=g+dy[i],ns=0; if(nx<0||ny<0||nx>2||ny>2)continue; //越界就不执行 swap(c[nx][ny],c[f][g]); for(ll i=0;i<3;i++) for(ll j=0;j<3;j++)ns=ns*10+c[i][j];//矩阵转数列 if(!m.count(ns)) { m[ns]=m[u]+1;//map去重的同时顺便统计到达这个状态所需的步数 q.push(ns); } swap(c[nx][ny],c[f][g]);//状态复原 } } cout<<m[123804765]<<endl; // map的下标直接用数列表示 return 0; }
- 1
信息
- ID
- 376
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者