NC19975 [HAOI2008]移动玩具
题目
题目描述
在一个4*4的方框内摆放了若干个相同的玩具,某人想将这些玩具重新摆放成为他心中理想的状态,规定移动时只能将玩具向上下左右四个方向移动,并且移动的位置不能有玩具,请你用最少的移动次数将初始的玩具状态移动到某人心中的目标状态。
输入描述
前4行表示玩具的初始状态,每行4个数字1或0,1表示方格中放置了玩具,0表示没有放置玩具。
接着是一个空行。接下来4行表示玩具的目标状态,每行4个数字1或0,意义同上。
输出描述
一个整数,所需要的最少移动次数。
示例1
输入
1111 0000 1110 0010 1010 0101 1010 0101
输出
4
题解
知识点:BFS,状压。
显然用bfs,将局面压缩进 位的二进制,搜索起始状态到目标状态的最短路径。每次扩展所有棋子上下左右四个方向,不要忘记更改局面状态。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> using namespace std; const int dir[4][2] = { {1,0},{-1,0},{0,1},{0,-1} }; int fin; bool vis[1 << 16]; struct node { int state, step; }st; int bfs(node st) { queue<node> q; q.push(st); vis[st.state] = 1; while (!q.empty()) { node cur = q.front(); q.pop(); if (cur.state == fin) return cur.step; for (int i = 0;i < 4;i++) { for (int j = 0;j < 4;j++) { if (!((cur.state >> (i * 4 + j)) & 1)) continue; for (int k = 0;k < 4;k++) { int xx = i + dir[k][0]; int yy = j + dir[k][1]; int sstate = (cur.state & ~(1 << (i * 4 + j))) | (1 << (xx * 4 + yy)); if (xx < 0 || xx >= 4 || yy < 0 || yy >= 4 || ((cur.state >> (xx * 4 + yy)) & 1) || vis[sstate]) continue; vis[sstate] = 1; q.push({ sstate,cur.step + 1 }); } } } } return -1; } int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); for (int i = 0;i < 4;i++) { for (int j = 0;j < 4;j++) { char c; cin >> c; if (c == '1') st.state |= 1 << (i * 4 + j); } } for (int i = 0;i < 4;i++) { for (int j = 0;j < 4;j++) { char c; cin >> c; if (c == '1') fin |= 1 << (i * 4 + j); } } st.step = 0; cout << bfs(st) << '\n'; return 0; }
本文来自博客园,作者:空白菌,转载请注明原文链接:https://www.cnblogs.com/BlankYang/p/16485045.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧