[挑战程序设计竞赛] AOJ 0121 - Seven Puzzle
2014-11-28 18:38
381 查看
题意:
7数码问题。在2×4的棋盘上,摆有7个棋子,每个棋子上标有1至7的某一数字,不同棋子上标的数字不相同。棋盘上还有一个空格(用0表示),与空格相邻(上下左右)的棋子可以移到空格中,该棋子原先位置成为空格。给出一个初始状态(保证可以转移到最终状态),找出一种从初始状态转变成给定最终状态的移动棋子步数最少的移动步骤。
输入:
多组输入,每组8个数,表示初始状态前四个数为第一行从左到右,后四个数为第二行从左到右。
输出:
至少需要多少步可以从输入状态到达最终状态(0 1 2 3 4 5 6 7)
由于空格相邻(上下左右)的数字可以移动到空格的位置上,可以把每种7数码的状态转化为一维的字符串,存储到Map中。每个空格位置,可以从四个方向移动过来。
这四个方向,对于一维的方向来说也是就,-1,1,4,-4。
排除越界的情况,还有一种特殊的情况,那就是位置3<--->位置4是不能交换的。需要特判!!!没有考虑到这个地方,被坑了好久。。
另外,题目询问的次数很多,我们可以倒着bfs一次,即可求出所有的开始状态走到最终状态的最少移动步骤~
7数码问题。在2×4的棋盘上,摆有7个棋子,每个棋子上标有1至7的某一数字,不同棋子上标的数字不相同。棋盘上还有一个空格(用0表示),与空格相邻(上下左右)的棋子可以移到空格中,该棋子原先位置成为空格。给出一个初始状态(保证可以转移到最终状态),找出一种从初始状态转变成给定最终状态的移动棋子步数最少的移动步骤。
输入:
多组输入,每组8个数,表示初始状态前四个数为第一行从左到右,后四个数为第二行从左到右。
输出:
至少需要多少步可以从输入状态到达最终状态(0 1 2 3 4 5 6 7)
由于空格相邻(上下左右)的数字可以移动到空格的位置上,可以把每种7数码的状态转化为一维的字符串,存储到Map中。每个空格位置,可以从四个方向移动过来。
这四个方向,对于一维的方向来说也是就,-1,1,4,-4。
排除越界的情况,还有一种特殊的情况,那就是位置3<--->位置4是不能交换的。需要特判!!!没有考虑到这个地方,被坑了好久。。
另外,题目询问的次数很多,我们可以倒着bfs一次,即可求出所有的开始状态走到最终状态的最少移动步骤~
#include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> #include <algorithm> #include <iostream> #include <set> #include <map> #include <queue> #include <stack> #include <assert.h> #include <time.h> //#define _Test typedef long long LL; const int INF = 500000001; const double EPS = 1e-9; const double PI = acos(-1.0); using namespace std; int a[15], dir[4]={1, -1, -4, 4}; char ch[15]; map<string, int> mm; struct p { char s[15]; int flag; }fir, en; queue<p> qq; bool check(int x, int y) { if(x < 0 || x >= 8) { return false; } if(x == 3 && y == 4 || x == 4 && y == 3) { return false; } return true; } void bfs() { while(!qq.empty()) { en = qq.front(); qq.pop(); for(int i = 0; i < 4; i++) { fir.flag = en.flag + dir[i]; if(check(fir.flag, en.flag)) { strcpy(fir.s, en.s); swap(fir.s[en.flag], fir.s[fir.flag]); if(mm.find(fir.s) == mm.end()) { mm[fir.s] = mm[en.s] + 1; qq.push(fir); } } } } } int main() { #ifdef _Test freopen("test0.in", "r", stdin); freopen("test0.out", "w", stdout); srand(time(NULL)); #endif char c[100]; while(~scanf("%d", &a[0])) { for(int i = 1; i < 8; i++) { scanf("%d", &a[i]); } for(int i = 0; i < 8; i++) { fir.s[i] = i + '0'; c[i] = a[i] + '0'; } c[8] = '\0'; fir.flag = 0; fir.s[8] = '\0'; mm[fir.s] = 1; qq.push(fir); bfs(); printf("%d\n", mm[c] - 1); } return 0; }
相关文章推荐
- [挑战程序设计竞赛] AOJ 0558 - Cheese
- [挑战程序设计竞赛] AOJ 0033 - Ball
- [挑战程序设计竞赛] AOJ 0118 - Property Distribution
- [挑战程序设计竞赛] AOJ 0525 - Osenbei
- ACM Radar Installation(挑战程序设计竞赛)
- poj1328 区间贪心 <挑战程序设计竞赛>
- 挑战程序设计竞赛(第2版)pdf
- [挑战程序设计竞赛] POJ 2376 - Cleaning Shifts
- 大背包问题(挑战程序设计竞赛)
- Seven Puzzle (AOJ 0121 bfs)
- 迷宫问题_BFS_挑战程序设计竞赛p34
- 挑战程序设计竞赛 2.5 它们其实都是“图”
- 挑战程序设计竞赛 2.1部分和问题
- 挑战编程 程序设计竞赛训练手册-1.6.4 液晶显示屏(LC-Display)
- 挑战程序设计竞赛2 算法和数据结构 读后感
- poj3190 区间贪心 <挑战程序设计竞赛>
- poj2229 基础的动态规划算法 <挑战程序设计竞赛>
- 常用技巧——集合的二进制整数表示(挑战程序设计竞赛)
- 挑战程序设计竞赛---POJ.3734(矩阵快速幂)
- Random Walk 挑战程序设计竞赛 期望值和方程组