本题的题目意思比较清晰:有4个齿轮,每一次可以向左或者向右转动一个齿轮,求两个数是否可到达,如果可以,则输出最短步骤数。 由此可见应该用bfs解决。 #include<stdio.h> #include<string.h> #include<queue> using namespace std; const int maxn = 10; int s, t; int f[4]; bool vis[10010]; void setVisited() { vis[f[0]*1000 + f[1]*100 + f[2]*10 + f[3]] = true; } bool getVisited() { return vis[f[0]*1000 + f[1]*100 + f[2]*10 + f[3]]; } struct node { int num; int step; }; int bfs() { node beg, tmp; int num; queue<node> q; beg.num = s; beg.step = 0; q.push(beg); while(!q.empty()) { beg = q.front(); q.pop(); if(beg.num == t) return beg.step; for(int i = 0; i < 4; i++) { num = beg.num; int cnt = 3; while(cnt >= 0) { f[cnt--] = num%10; num /= 10; } f[i] = (f[i]-1+maxn)%maxn; //注意这里可能会有溢出情况的发生 if(!getVisited()) { setVisited(); num = f[0]*1000 + f[1]*100 + f[2]*10 + f[3]; tmp.num = num; // printf("%d/n", num); tmp.step = beg.step + 1; q.push(tmp); } num = beg.num; cnt = 3; while(cnt >= 0) { f[cnt--] = num%10; num /= 10; } f[i] = (f[i]+1)%maxn; if(!getVisited()) { setVisited(); num = f[0]*1000 + f[1]*100 + f[2]*10 + f[3]; tmp.num = num; // printf("%d/n", num); tmp.step = beg.step + 1; q.push(tmp); } } } return -1; } #define LOCAL int main() { #ifdef LOCAL freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout); #endif int test; scanf("%d", &test); while(test--) { memset(vis, false, sizeof(vis)); for(int i = 0; i < 4; i++) scanf("%d", &f[i]); setVisited(); s = f[0]*1000 + f[1]*100 + f[2]*10 + f[3]; for(int i = 0; i < 4; i++) scanf("%d", &f[i]); t = f[0]*1000 + f[1]*100 + f[2]*10 + f[3]; // printf("%d %d/n", s, t); int n; scanf("%d", &n); for(int i = 0; i < n; i++) { for(int j = 0; j < 4; j++) scanf("%d", &f[j]); // printf("%d/n", f[0]*1000 + f[1]*100 + f[2]*10 + f[3]); setVisited(); } printf("%d/n", bfs()); } return 0; }