HDU1195 ZOJ2416 Open the Lock

来源:互联网 发布:穿越火线mac可以玩吗 编辑:程序博客网 时间:2024/05/20 04:09
问题链接HDU1195 ZOJ2416 Open the Lock

题意简述:输入测试用例数t,每个例子包括两个4个数字的整数(由1到9组成),一个为源,另外一个为目标。每次可以将其中任何一个数字+1或者-1运算,并且规定1-1=9,9+1=1;也可以将相邻2位数进行交换。问最少需要变换几次,才能从源变为目标。

问题分析:该问题可以用BFS来解决。在BFS搜索过程中,出现过的4位数就不必再试探了,因为再用这个4位数变下去其次数不可能比上次开始的变换次数少。

程序说明:每个节点既保存4位整数值,也分别保存4位数字于数组中,有利于变换也有利于比较。编写了函数myatoi()用于将数字的值串(不是数字字符的串)转换为整数。数组notvist[]用于避免重复搜索。

本程序虽然略长,但是程序逻辑清晰易懂。

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;}


1 0