输入T,
然后每组数据给两个四位字符串(1 ~9),问从第一个字符串转化为第二个字符串最少需要几步。转化方式有两种,一是每个数字位加一或减一(9+1=1,1-1=9),二是相邻两位可以交换(最头最末两位不相邻)。
利用一个数组来剪枝。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
char a[5], b[5];
struct node {
char str[5];
int num;
};
int book[10][10][10][10];
void bfs() {
queue <node> q;
node cur, next;
cur.num = 0, strcpy(cur.str, a);
book[a[0] - '0'][a[1] - '0'][a[2] - '0'][a[3] - '0'] = 1;
q.push(cur);
while(!q.empty()) {
cur = q.front();
if(strcmp(cur.str, b) == 0) {
printf("%d\n", cur.num);
return;
}
q.pop();
int i;
for(i = 0; i < 4; i++) {
strcpy(next.str, cur.str);
cur.str[i] == '9' ? next.str[i] = '1' : next.str[i]++;
next.num = cur.num + 1;
if(book[next.str[0] - '0'][next.str[1] - '0'][next.str[2] - '0'][next.str[3] - '0'] == 0) {
book[next.str[0] - '0'][next.str[1] - '0'][next.str[2] - '0'][next.str[3] - '0'] = 1;
q.push(next);
}
strcpy(next.str, cur.str);
cur.str[i] == '1' ? next.str[i] = '9' : next.str[i]--;
next.num = cur.num + 1;
if(book[next.str[0] - '0'][next.str[1] - '0'][next.str[2] - '0'][next.str[3] - '0'] == 0) {
book[next.str[0] - '0'][next.str[1] - '0'][next.str[2] - '0'][next.str[3] - '0'] = 1;
q.push(next);
}
}
for(i = 0; i < 3; i++) {
strcpy(next.str, cur.str);
char tmp = next.str[i];
next.str[i] = next.str[i + 1];
next.str[i + 1] = tmp;
next.num = cur.num + 1;
if(book[next.str[0] - '0'][next.str[1] - '0'][next.str[2] - '0'][next.str[3] - '0'] == 0) {
book[next.str[0] - '0'][next.str[1] - '0'][next.str[2] - '0'][next.str[3] - '0'] = 1;
q.push(next);
}
}
}
}
int main() {
int T;
scanf("%d", &T);
while(T--) {
scanf("%s", a);
scanf("%s", b);
memset(book, 0, sizeof(book));
bfs();
}
return 0;
}