题目链接:here
给你四个数字,每次可以将其中任何一个数字 +1 或者 -1 ; 1的时候-1 等于9 ;9的时候+1 等于1; 问最少需要变换几次,才可以变到目标序列。。
我先用广搜做了一遍,随后又用双向广搜做了一遍,发现双向广搜效率的确很高!
贴一下图:
第一个是双向广搜的,下面的是广搜。。。
#include <iostream> #include <cstdio> #include <queue> #include <cstring> using namespace std; struct node { int num[4]; int step; }; queue<node> q; bool vis[10][10][10][10]; int ansnum[4]; int ans; int dir[8][4] = {{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1},{-1,0,0,0},{0,-1,0,0},{0,0,-1,0},{0,0,0,-1}}; void init() { memset(vis, false, sizeof(vis)); while (!q.empty()) q.pop(); } bool istrue(node x) { if (x.num[0] == ansnum[0] && x.num[1] == ansnum[1] && x.num[2] == ansnum[2] && x.num[3] == ansnum[3]) return true; return false; } bool judge(node x) { if (vis[x.num[0]][x.num[1]][x.num[2]][x.num[3]]) return false; return true; } node change(node a, int b) { a.step ++; if (b < 4) // + { if (a.num[b] == 9) a.num[b] = 1; else a.num[b] ++; } else if (b < 8) // - { if (a.num[b%4] == 1) a.num[b%4] = 9; else a.num[b%4] = a.num[b%4] - 1; } else // 换 { int tmp; b %= 4; tmp = a.num[b]; a.num[b] = a.num[b+1]; a.num[b+1] = tmp; } return a; } void bfs() { node now, next; while (!q.empty()) { now = q.front(); q.pop(); if (istrue(now)) { ans = now.step; return ; } for (int i = 0; i < 11; i++) { next = change(now, i); if (judge(next)) { vis[next.num[0]][next.num[1]][next.num[2]][next.num[3]] = true; q.push(next); } } } } int main() { int T; scanf("%d", &T); while (T--) { init(); int a, b; node now; scanf("%d %d", &a, &b); for (int i=3; i>=0; i--) { ansnum[i] = a % 10; now.num[i] = b % 10; a /= 10; b /= 10; } now.step = 0; q.push(now); vis[now.num[0]][now.num[1]][now.num[2]][now.num[3]] = true; bfs(); printf("%d\n", ans); } return 0; }
#include <iostream> #include <cstdio> #include <queue> #include <cstring> using namespace std; struct node { int num[4]; int step; }; queue<node> q[2]; int vis[2][10][10][10][10]; int ansnum[4]; int ans; void init() { ans = -1; memset(vis, -1, sizeof(vis)); while (!q[0].empty()) q[0].pop(); while (!q[1].empty()) q[1].pop(); } bool istrue(node x, int i) { if (vis[1^i][x.num[0]][x.num[1]][x.num[2]][x.num[3]] != -1) return true; return false; } bool judge(node x, int i) { if (vis[i][x.num[0]][x.num[1]][x.num[2]][x.num[3]] != -1) return false; return true; } node change(node a, int b) { a.step ++; if (b < 4) // + { if (a.num[b] == 9) a.num[b] = 1; else a.num[b] ++; } else if (b < 8) // - { if (a.num[b%4] == 1) a.num[b%4] = 9; else a.num[b%4] = a.num[b%4] - 1; } else // 换 { int tmp; b %= 4; tmp = a.num[b]; a.num[b] = a.num[b+1]; a.num[b+1] = tmp; } return a; } void bfs(int j) { node now, next; if (ans != -1 || q[j].empty()) return ; int first = q[j].front().step; while (!q[j].empty() && q[j].front().step == first) { now = q[j].front(); q[j].pop(); if (istrue(now, j)) { ans = vis[j][now.num[0]][now.num[1]][now.num[2]][now.num[3]] + vis[1^j][now.num[0]][now.num[1]][now.num[2]][now.num[3]]; return ; } for (int i = 0; i < 11; i++) { next = change(now, i); if (judge(next, j)) { vis[j][next.num[0]][next.num[1]][next.num[2]][next.num[3]] = next.step; q[j].push(next); } } } } void db_bfs() { while (ans == -1) { bfs(0); bfs(1); } } int main() { int T; scanf("%d", &T); while (T--) { init(); int a, b; node now0, now1; scanf("%d %d", &a, &b); for (int i=3; i>=0; i--) { now0.num[i] = a % 10; now1.num[i] = b % 10; a /= 10; b /= 10; } now0.step = 0; q[0].push(now0); vis[0][now0.num[0]][now0.num[1]][now0.num[2]][now0.num[3]] = 0; now1.step = 0; q[1].push(now1); vis[1][now1.num[0]][now1.num[1]][now1.num[2]][now1.num[3]] = 0; db_bfs(); printf("%d\n", ans); } return 0; }