标签:
这题应该算是经典的八数码问题的弱化版吧:给你一个4x2的方版,上面有0-7 八个数字,每次只能让编号0的方格跟他的上下左右的方格交换;所以也就是把方格0当做空格看待,每次只有空格周围的方格能够向空格处移动。 然后问从输入的方格样式变换到字典序最小的"01234567" 最少需要多少次。
解法是用bfs 求最少次数(跟求最短路径方式类似)。 我这里用的是打表的方法:对于方格的状态,我是用string来存的,下标0-7分别表示从左到右,从上到下的方格上的数字。 一开始队列中只放入"01234567"的状态; 然后从它开始进行bfs, 用个map<string,int> 来存放已得到的状态和需要的步数; 同时 这个map也是用来判重的。 而方格0的移动的话, 每次只有上下左右,因为是用字符串存状态的,所以对应上下左右 其字符所在下标的变换就是{-4,+4,-1,+1}; 注意变换后下标是否在0-7范围内以及0原始位置是在左下角和右上角的特殊情况。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <cstdlib> 7 #include <cctype> 8 #include <queue> 9 #include <stack> 10 #include <map> 11 #include <vector> 12 #include <set> 13 #include <utility> 14 #define ll long long 15 #define inf 0x3f3f3f3f 16 using namespace std; 17 18 typedef pair<string,int> P; 19 string str; 20 map<string,int> table; 21 int dir[]= {-1,1,-4,4}; //移动方向 22 void bfs() 23 { 24 queue<P> q; 25 string s,s_next; 26 P temp; 27 int cur,next; 28 q.push(P("01234567",0)); 29 table["01234567"]=0; 30 while(!q.empty()) 31 { 32 temp=q.front(); 33 q.pop(); 34 s=temp.first; 35 cur=temp.second; 36 for(int i=0; i<4; i++)//将0向四个方向移动 37 { 38 next=cur+dir[i]; 39 str=s; 40 swap(str[cur],str[next]); 41 if(next>=0&&next<8&&!(cur==3&&next==4)&&!(cur==4&&next==3)&&table.find(str)==table.end()) 42 { //判断移动是否合法及该状态是否已存在 43 table[str]=table[s]+1; 44 q.push(P(str,next)); 45 } 46 } 47 } 48 } 49 int main() 50 { 51 //freopen("input.txt","r",stdin); 52 char sstr[50]; 53 bfs(); 54 while(gets(sstr)) 55 { 56 for(int i=1; i<8; i++) 57 sstr[i]=sstr[i*2]; 58 sstr[8]=‘\0‘; 59 str=sstr; 60 printf("%d\n",table[str]); 61 } 62 }
标签:
原文地址:http://www.cnblogs.com/geek1116/p/5672991.html