双端BFS
先占个坑(开两个queue的方法,先占个坑)
1.思想简介和伪代码:此处只开一个queue
2.第一个例题:
800ms代码:找到了对方已经访问过的代码就退出循环,然后再queue里面找到对应的状态的步数(这一步十分耗时)
200ms代码:将 步数 和 是从谁搜索到的 打包成一个Pair,作为map的second存起来(下面给出代码)
#include<iostream> #include<queue> #include<map> using namespace std; typedef pair<int, int> pai; int nextx[4] = {0, 0, 1, -1}, nexty[4] = {1, -1, 0, 0}; int creat(int state, int k) { int x, y; int a[3][3]; for(int i = 2; i >= 0; i--) for(int j = 2; j >= 0; j--) { a[i][j] = state%10; state/=10; } for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++) { if(a[i][j] == 0) { x = i; y = j; break; } } int x1 = x + nextx[k]; int y1 = y + nexty[k]; if(0<=x1 && x1<3 && 0<=y1 && y1<3) { a[x][y] = a[x1][y1]; a[x1][y1] = 0; } else return -1; int ans = 0; for(int i = 0; i < 3; i++) { for(int j = 0; j < 3; j++) { ans *= 10; ans += a[i][j]; } } return ans; } int n, m = 123804765; void bfs() { map<int, pai> ma; queue<int> q; q.push(n); ma[n] = make_pair(1, 0); q.push(m); ma[m] = make_pair(2, 0); int ans = 0; while(!q.empty()) { int now = q.front(); q.pop(); for(int i = 0; i < 4; i++) { int next = creat(now, i); if(next == -1) continue;//不能走这一个方向 if(ma[next].first == NULL)//没访问过 { pai tmp = ma[now]; ma[next] = make_pair(tmp.first, tmp.second+1); q.push(next); } else if(ma[next].first != ma[now].first)//对家访问过,路线就串起来了 { ans = ma[next].second + ma[now].second+1; cout << ans << endl; return ; } //自家访问过,那就进行最优剪枝 } } return ; } int main() { cin >> n; if(n == m) cout <<0<<endl; else bfs(); return 0; }

浙公网安备 33010602011771号