标签:
问题链接:HDU1195 ZOJ2416 Open the Lock。题意简述:输入测试用例数t,每个例子包括两个4个数字的整数(由1到9组成),一个为源,另外一个为目标。每次可以将其中任何一个数字+1或者-1运算,并且规定1-1=9,9+1=1;也可以将相邻2位数进行交换。问最少需要变换几次,才能从源变为目标。
问题分析:该问题可以用BFS来解决。在BFS搜索过程中,出现过的4位数就不必再试探了,因为再用这个4位数变下去其次数不可能比上次开始的变换次数少。数组notvist[]用于避免重复搜索。
程序中,每个节点既保存4位整数值,也分别保存4位数字于数组中,有利于变换也有利于比较。编写了函数myatoi()用于将数字的值串(不是数字字符的串)转换为整数。
本程序虽然略长,但是程序逻辑清晰易懂。
AC的C++语言程序如下:
/* HDU1195 ZOJ2416 Open the Lock */ #include <iostream> #include <cstring> #include <queue> using namespace std; const int MAXN = 4; struct node { char num[MAXN+1]; int a; int level; }; node start; int b; bool notvist[10000]; int myatoi(char *s) { int result = 0; while(*s) { result *= 10; result += *s; s++; } return result; } int bfs() { int i, temp = start.a; for(i=0; i<MAXN; i++) { start.num[MAXN - 1 - i] = temp % 10; temp /= 10; } start.num[i] = '\0'; start.level = 0; notvist[start.a] = false; memset(notvist, true, sizeof(notvist)); queue<node> q; q.push(start); while(!q.empty()) { node front = q.front(); q.pop(); if(myatoi(front.num) == b) return front.level; node v; // exchange for(i=1; i<=MAXN-1; i++) { strcpy(v.num, front.num); int t = v.num[i-1]; v.num[i-1] = v.num[i]; v.num[i] = t; v.a = myatoi(v.num); if(notvist[v.a]) { v.level = front.level + 1; q.push(v); notvist[v.a] = false; } } // plus 1 for(i=0; i<MAXN; i++) { strcpy(v.num, front.num); v.num[i]++; if(v.num[i] == 10) v.num[i] = 1; v.a = myatoi(v.num); if(notvist[v.a]) { v.level = front.level + 1; q.push(v); notvist[v.a] = false; } } // minus 1 for(i=0; i<MAXN; i++) { strcpy(v.num, front.num); v.num[i]--; if(v.num[i] == 0) v.num[i] = 9; v.a = myatoi(v.num); if(notvist[v.a]) { v.level = front.level + 1; q.push(v); notvist[v.a] = false; } } } return 0; } int main() { int t, ans; cin >> t; while(t--) { cin >> start.a >> b; ans = bfs(); cout << ans << endl; } return 0; }
标签:
原文地址:http://blog.csdn.net/tigerisland45/article/details/52179199