题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1195 , 双向BFS或者直接BFS也可以过。
其实这道题只是单向BFS就可以过的,但是为了练算法,所以还是用了双向BFS来写。
算法:
先预处理一下,从1111到9999的所有点进行构图(由于是1~9的,所以除去含有0元素的数字),能进行一次变换变成的数字则表示两点之间连通。然后从初态与目态两个点进行BFS,如果有轨迹重合的就返回路程和。
这里注意双向BFS要一层一层的进行搜索,不然的话会产生错误,至于错误原因还在思考中。。
双向BFS代码:
#include <iostream> #include <cstdio> #include <vector> #include <queue> #include <cmath> #include <string> #include <string.h> #include <algorithm> using namespace std; #define LL __int64 #define eps 1e-8 #define INF 1e8 #define lson l , m , rt << 1 #define rson m + 1 , r , rt << 1 | 1 const int MOD = 2333333; const int maxn = 10000 + 5; vector <int> e[maxn]; int vis[maxn] , dist[maxn]; void solve(int x) { int num[4] , i , tmp , y; i = 0; tmp = x; while(tmp) { num[i++] = tmp % 10; tmp /= 10; } for(i = 0 ; i < 4 ; i++) if(num[i] == 0) return; for(i = 0 ; i < 4 ; i++) { if(i < 3) { swap(num[i] , num[i + 1]); y = num[3] * 1000 + num[2] * 100 + num[1] * 10 + num[0]; e[x].push_back(y); e[y].push_back(x); swap(num[i] , num[i + 1]); } tmp = num[i]; if(num[i] == 9) num[i] = 1; else num[i]++; y = num[3] * 1000 + num[2] * 100 + num[1] * 10 + num[0]; e[x].push_back(y); e[y].push_back(x); num[i] = tmp; if(num[i] == 1) num[i] = 9; else num[i]--; y = num[3] * 1000 + num[2] * 100 + num[1] * 10 + num[0]; e[x].push_back(y); e[y].push_back(x); num[i] = tmp; } } int BFS_2(int start , int end) { if(start == end) return 0; memset(vis , 0 , sizeof(vis)); queue <int> que[2]; vis[start] = 1; vis[end] = 2; que[0].push(start); que[1].push(end); dist[start] = dist[end] = 0; while(!que[0].empty() && !que[1].empty()) { int k = 0; if(que[0].size() < que[1].size()) k++; int u = que[k].front(); que[k].pop(); for(int i = 0 ; i < e[u].size() ; i++) { int j = e[u][i]; if(!vis[j]) { vis[j] = vis[u]; que[k].push(j); dist[j] = dist[u] + 1; } else if(vis[j] == vis[u]) { continue; } else { return dist[j] + dist[u] + 1; } } } return -1; } int main() { int T , a , b; for(int i = 1111 ; i <= 9999 ; i++) solve(i); cin >> T; while(T--) { scanf("%d %d" , &a , &b); printf("%d\n" , BFS_2(a , b)); } return 0; }
BFS代码:
#include <iostream> #include <cstdio> #include <vector> #include <queue> #include <cmath> #include <string> #include <string.h> #include <algorithm> using namespace std; #define LL __int64 #define eps 1e-8 #define INF 1e8 #define lson l , m , rt << 1 #define rson m + 1 , r , rt << 1 | 1 const int MOD = 2333333; const int maxn = 10000 + 5; vector <int> e[maxn]; int vis[maxn] , dist[maxn]; void solve(int x) { int num[4] , i , tmp , y; i = 0; tmp = x; while(tmp) { num[i++] = tmp % 10; tmp /= 10; } for(i = 0 ; i < 4 ; i++) if(num[i] == 0) return; for(i = 0 ; i < 4 ; i++) { if(i < 3) { swap(num[i] , num[i + 1]); y = num[3] * 1000 + num[2] * 100 + num[1] * 10 + num[0]; e[x].push_back(y); e[y].push_back(x); swap(num[i] , num[i + 1]); } tmp = num[i]; if(num[i] == 9) num[i] = 1; else num[i]++; y = num[3] * 1000 + num[2] * 100 + num[1] * 10 + num[0]; e[x].push_back(y); e[y].push_back(x); num[i] = tmp; if(num[i] == 1) num[i] = 9; else num[i]--; y = num[3] * 1000 + num[2] * 100 + num[1] * 10 + num[0]; e[x].push_back(y); e[y].push_back(x); num[i] = tmp; } } int BFS(int a , int b) { if(a == b) return 0; memset(vis , 0 , sizeof(vis)); queue <int> que; que.push(a); vis[a] = 1; dist[a] = 0; while(!que.empty()) { int u = que.front(); que.pop(); for(int i = 0 ; i < e[u].size() ; i++) { int j = e[u][i]; if(j == b) return dist[u] + 1; if(!vis[j]) { dist[j] = dist[u] + 1; vis[j] = 1; que.push(j); } } } } int main() { int T , a , b; for(int i = 1111 ; i <= 9999 ; i++) solve(i); cin >> T; while(T--) { scanf("%d %d" , &a , &b); printf("%d\n" , BFS(a , b)); } return 0; }
时间: 2024-07-30 10:20:04