题意简述:输入测试用例数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