神奇密码锁 bfs

来源:互联网 发布:网络摄像机监控软件 编辑:程序博客网 时间:2024/06/05 11:29

问题 D: 神奇密码锁

时间限制: 2 Sec  内存限制: 128 MB
提交: 204  解决: 53
[提交][状态][讨论版]

题目描述

 小明忘记了旅行箱上的密码,现在他想自己暴力弄出密码来,但他又想知道最从一个数字到另一个数字最少需要多少步,现在请你帮忙。

另外,小明的密码箱很奇怪,只有四位数,上面的数字只有1到9,每次只能让每位数加1或者减1。按常识我们可以知道从1到9只需要减1,从9到1只需要加1。此外,你还能交换相邻的两个数字。如1234可以在一步后变成2134,但不能变成4231。

输入

第一行有一个整数:T,代表有多少组测试数据。

接下来T行,每行有两个整数(都是四位数),第一个是初状态,第二个是目标状态。

输出

每组数据输出一个整数,占一行。

样例输入

21234 21441111 9999

样例输出

24

提示

#include <iostream>#include <cstdio>#include <cstring>#include <queue>using namespace std;int st[6],goal[6];char st0[6],goal0[6];int visti[10000];int ans;struct data {    int s[6];    int sum;};//queue <data> que;bool check(int s[]){    int t=(s[0])*1000+(s[1])*100+(s[2])*10+(s[3]);    if(!visti[t]){        visti[t]=1;//标记为已访问        return true;    }    return false;}void bfs() {    queue <data> que;    data p;    memcpy(p.s,st,sizeof(st));    p.sum=0;    if(check(p.s))      que.push(p);    while(!que.empty()) {        p=que.front();        que.pop();        if(!memcmp(p.s,goal,sizeof(goal))) {            ans=p.sum;            return ;        }        for(int j=0; j<4; j++) {            int t=p.s[j];            p.sum++;            if(p.s[j]<9) p.s[j]++;            else p.s[j]=1;            if(check(p.s))                que.push(p);            p.s[j]=t;            if(p.s[j]>1) p.s[j]--;            else p.s[j]=9;            if(check(p.s))                que.push(p);            p.s[j]=t;            if(j<3) {                int temp;                temp=p.s[j+1];                p.s[j+1]=p.s[j];                p.s[j]=temp;                if(check(p.s))                    que.push(p);                p.s[j]=t;                p.s[j+1]=temp;            }            p.sum--;        }    }}int main() {    int n;    scanf("%d",&n);    while(n--) {        ans=0;        scanf("%s%s",st0,goal0);        for(int i=0;i<4;i++)        {            st[i]=st0[i]-'0';            goal[i]=goal0[i]-'0';        }        memset(visti,0,sizeof(visti));        bfs();        printf("%d\n",ans);    }}


下面的代码,想尝试用A*算法,写的,但是在求H(n)的函数那里找不到一个好的办法,所以导致超时了。留在这里日后思考。如果有路过的大神知道如何修改,可以私聊我。QQ:751479173

#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <math.h>#include <stdio.h>#include <stdlib.h>using namespace std;int st[6],goal[6];char st0[6],goal0[6];int visti[10000];int ans;struct data {    int s[6];    int sum;    int g,h,f;    bool operator < (const data & k) const {     //重载比较运算符        if(f==k.f)            return g>k.g;        return f > k.f;    }};//queue <data> que;bool check(int s[]) {    int t=(s[0])*1000+(s[1])*100+(s[2])*10+(s[3]);    if(!visti[t]) {        visti[t]=1;//标记为已访问        return true;    }    return false;}int bianhao(int s[]) {    int t;    return  t=(s[0])*1000+(s[1])*100+(s[2])*10+(s[3]);}int wrongPlaceNum(int a[]) { //求不在位的数字个数    int cnt=0;    for(int i=0; i<4; i++)        if(a[i]!=goal[i]) cnt++;    return cnt;}void bfs() {    priority_queue <data> que;    data p,q;    memcpy(q.s,st,sizeof(st));    q.sum=p.g=0;    q.h=wrongPlaceNum(q.s);    q.f=q.g+q.h;    if(check(q.s))        que.push(q);    while(!que.empty()) {        q=que.top();        que.pop();        if(!memcmp(q.s,goal,sizeof(goal))) {            ans=q.sum;            return ;        }        for(int j=0; j<4; j++) {            memcpy(&p,&q,sizeof(q));            if(p.s[j]<9) p.s[j]++;            else p.s[j]=1;            if(check(p.s)) {                p.g=p.g+1;                p.h=wrongPlaceNum(p.s);                p.f=p.g+p.h;                p.sum++;                que.push(p);            }            memcpy(&p,&q,sizeof(q));            if(p.s[j]>1) p.s[j]--;            else p.s[j]=9;            if(check(p.s)) {                p.g=p.g+1;                p.h=wrongPlaceNum(p.s);                p.f=p.g+p.h;                p.sum++;                que.push(p);            }            memcpy(&p,&q,sizeof(q));            if(j<3) {                int temp;                temp=p.s[j+1];                p.s[j+1]=p.s[j];                p.s[j]=temp;                if(check(p.s)) {                    p.g=p.g+1;                    p.h=wrongPlaceNum(p.s);                    p.f=p.g+p.h;                    p.sum++;                    que.push(p);                }            }            memcpy(&p,&q,sizeof(q));        }    }}int main() {    int n;    scanf("%d",&n);    while(n--) {        ans=0;        scanf("%s%s",st0,goal0);        for(int i=0; i<4; i++) {            st[i]=st0[i]-'0';            goal[i]=goal0[i]-'0';        }        memset(visti,0,sizeof(visti));        bfs();        printf("%d\n",ans);    }}


原创粉丝点击