标签:
题目链接:http://poj.org/problem?id=1184
分析:首先可以发现有6*10^6种状态,比较多,不过搜索的时候可以去除一些无用的状态,
可以发现一个点的值(2-5)如果想要改变那么光标必须在该点处,
所以当光标在2-5位置时候,必须要要把值变为与目标位置处一样才可以移动。
单搜:
#include<stdio.h> #include<queue> #include<string.h> #include<algorithm> using namespace std; #define N 1000002 int vis[7][N]; int a0[10], b0[10], A, B; struct node { int k;///光标所在位置 int num; int step; }; void FenNum(int n, int a[])///把n的每位数字存到a数组中; { int i=6; while(i) { a[i--]=n%10; n/=10; } } node Op(int a[], int op, node p) { if(op==0) swap(a[p.k], a[1]); if(op==1) swap(a[p.k], a[6]); if(op==2 && a[p.k]!=9) a[p.k]++; if(op==3 && a[p.k]!=0) a[p.k]--; if(op==4 && p.k!=1) p.k--; if(op==5 && p.k!=6) p.k++; p.num=0; for(int i=1; i<=6; i++) p.num = p.num*10+a[i]; return p; } int bfs(int num) { node p; queue<node>Q; p.k=1; p.num = num; p.step = 0; Q.push(p); memset(vis, 0, sizeof(vis)); vis[p.k][p.num] = 1; while(Q.size()) { p=Q.front(); Q.pop(); if(p.num==B) return p.step; for(int i=0; i<6; i++) { FenNum(p.num, a0); if((i==4||i==5) && p.k<=5 && p.k>=2 && a0[p.k]!=b0[p.k]) continue; node pn = Op(a0, i, p); if(vis[pn.k][pn.num]==0) { pn.step=p.step+1; Q.push(pn); vis[pn.k][pn.num] = 1; } } } return -1; } int main() { scanf("%d%d", &A, &B); FenNum(B, b0); int ans = bfs(A); printf("%d\n", ans); }
双搜:(我只看了看)
#include<stdio.h> #include<queue> #include<algorithm> using namespace std; const int MAXN = 1e6; char used[MAXN][2][7]; struct node { int pass[7];///保存密码 int cursor;///光标所在位置 int op;///op等于0表示从原始密码开始,等于1表示从目标密码开始 int step;///步数 }; int TurnNum(node s) { int sum=0; for(int i=1; i<7; i++) sum = sum*10 + s.pass[i]; return sum; } void TurnStr(node &s, int M) { for(int i=6; i>0; i--) { s.pass[i] = M % 10; M /= 10; } } int BFS(node s, node e) { queue<node> Q; Q.push(s); int k = TurnNum(s); used[k][0][1] = true; k = TurnNum(e); for(int i=1; i<7; i++) { e.cursor = i; used[k][1][i] = true; Q.push(e); } int p[2][7]; for(int i=1; i<=6; i++) {///保存一下原始密码,和目标密码 p[0][i] = s.pass[i]; p[1][i] = e.pass[i]; } while(Q.size()) { s = Q.front(); Q.pop(); for(int i=1; i<=6; i++) { e = s; if(i == 1) swap(e.pass[e.cursor], e.pass[1]); else if(i == 2) swap(e.pass[e.cursor], e.pass[6]); else if(i == 3 && e.pass[e.cursor] != 9) e.pass[e.cursor] += 1; else if(i == 4 && e.pass[e.cursor] != 0) e.pass[e.cursor] -= 1; else if(i == 5 && ( (e.cursor>=2 && e.cursor<=5 && e.pass[e.cursor]==p[e.op^1][e.cursor]) || e.cursor==6) ) e.cursor -= 1; else if(i == 6 && ( (e.cursor>=2 && e.cursor<=5 && e.pass[e.cursor]==p[e.op^1][e.cursor]) || e.cursor==1) ) e.cursor += 1; k = TurnNum(e); if(used[k][e.op][e.cursor] == 0) { if(used[k][e.op^1][e.cursor]) { return used[k][e.op^1][e.cursor] + e.step-1; } e.step += 1; used[k][e.op][e.cursor] = e.step; Q.push(e); } } } return -1; } int main() { int S, E; node s, e; scanf("%d%d", &S, &E); if(S == E) { printf("%d\n", 0); return 0; } TurnStr(s, S); TurnStr(e, E); s.cursor = 1, s.op = 0, s.step = 1; e.op = 1, e.step = 1; int ans = BFS(s, e); printf("%d\n", ans); return 0; }
标签:
原文地址:http://www.cnblogs.com/zhengguiping--9876/p/4741476.html