搜索 问题 D: 神奇密码锁

news/2024/7/7 16:00:59

这里写图片描述
这道题个人认为隐含着状态转换,所以想到的还是BFS,将其中一位数加一或减一或交换临近两位,进入下一状态,使用一个大小为10000的bool数组判重,由于BFS的特性,得到的一定是最小步数;
普通BFS代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
using namespace std;
const int MaxSize = 1e5;
typedef struct node{
    int a[4];
    int step;
}Node;

Node Q[MaxSize];

bool visit[10005];

bool search_table(int *a){
    int tmp=0;
    tmp = a[0]*1000+a[1]*100+a[2]*10+a[3];
    if(visit[tmp])return false;
    visit[tmp] = true;
    return true;
}

int BFS(int *start,int *goal){
    int head=0,tail=1,tmp;
    memset(visit,0,sizeof(visit));
    Node t,s;
    memcpy(t.a,start,4*sizeof(int));
    t.step = 0;
    Q[head] = t;
    while(head!=tail){
        t = Q[head];
        if(!memcmp(t.a,goal,4*sizeof(int))) return t.step;
        for(int i=0;i<4;i++){
            s = t;
            s.a[i]++;
            s.step++;
            if(s.a[i]>9) s.a[i]=1;
            if(search_table(s.a)) {
                    Q[tail]=s;
            tail=(tail+1)%MaxSize;
            }
        }
        for(int i=0;i<4;i++){
            s = t;
            s.a[i]--;
            s.step++;
            if(s.a[i]<1) s.a[i]=9;
            if(search_table(s.a)) {
                    Q[tail]=s;
            tail=(tail+1)%MaxSize;
            }
        }
        for(int i=0;i<3;i++){
            s = t;
            tmp = s.a[i],s.a[i] = s.a[i+1],s.a[i+1] = tmp;
            s.step++;
            if(search_table(s.a)) {
                    Q[tail]=s;
            tail=(tail+1)%MaxSize;
            }
        }
        head=(head+1)%MaxSize;
    }
    return -1;
}

void Input_data(int *start,int *goal){
    char c[5];
    scanf("%s",c);
    for(int i=0;i<4;i++) start[i] = c[i]-'0';
    scanf("%s",c);
    for(int i=0;i<4;i++) goal[i] = c[i]-'0';
}

int main(){
    int T,start[4],goal[4];
    scanf("%d",&T);
    while(T--){
        Input_data(start,goal);
        printf("%d\n",BFS(start,goal));
    }
}

双向BFS:

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

int visit[10005];
const int MaxSize = 1e5;
typedef struct node{
    int a[4],step;
}Node;
Node start,goal;
int trans(Node x){
    int tmp = 0;
    for(int i=0;i<4;i++) tmp = tmp*10+x.a[i];
    //printf("%d\n",tmp);
    return tmp;
}

Node Q1[MaxSize],Q2[MaxSize];

int BFS(){
    memset(visit,0,sizeof(visit));
    //queue<Node> Q1,Q2;

    Node t,s;
    int step1=0,step2=0,ans,cnt;
    int head1=0,head2=0,tail1=1,tail2=1;
    start.step = 0;
    goal.step = 0;
    Q1[head1] = start;
    Q2[head2] = goal;
    visit[trans(start)]=1;
    visit[trans(goal)]=2;
    while(true){
            cnt = (tail1-head1+MaxSize)%MaxSize;
            while(cnt--){
                t = Q1[head1];
                if(!memcmp(t.a,goal.a,sizeof(goal.a))) return t.step;
                step1 = t.step + 1;
                for(int i=0;i<4;i++){
                    s = t;
                    s.a[i]++;
                    if(s.a[i]>9) s.a[i]=1;
                    ans = trans(s);
                    if(visit[ans]==2) return step1+step2;
                    if(!visit[ans]){
                        visit[ans] = 1;
                        s.step = step1;
                        Q1[tail1]=s;
                        tail1=(tail1+1)%MaxSize;
                    }
                }
                 for(int i=0;i<4;i++){
                    s = t;
                    s.a[i]--;
                    if(s.a[i]<1) s.a[i]=9;
                    ans = trans(s);
                    if(visit[ans]==2) return step1+step2;
                    if(!visit[ans]){
                        visit[ans] = 1;
                        s.step = step1;
                        Q1[tail1]=s;
                        tail1=(tail1+1)%MaxSize;
                    }
                }
                for(int i=0;i<3;i++){
                    s = t;
                    swap(s.a[i],s.a[i+1]);
                    ans = trans(s);
                    if(visit[ans]==2) return step1+step2;
                    if(!visit[ans]){
                        visit[ans] = 1;
                        s.step = step1;
                        Q1[tail1]=s;
                        tail1=(tail1+1)%MaxSize;
                    }
                }
                head1=(head1+1)%MaxSize;
            }
            cnt = (tail2-head2+MaxSize)%MaxSize;
            while(cnt--){
                 t = Q2[head2];
                if(!memcmp(t.a,start.a,sizeof(start.a))) return t.step;
                step2 = t.step + 1;
                for(int i=0;i<4;i++){
                    s = t;
                    s.a[i]++;
                    if(s.a[i]>9) s.a[i]=1;
                    ans = trans(s);
                    if(visit[ans]==1) return step1+step2;
                    if(!visit[ans]){
                        visit[ans] = 2;
                        s.step = step2;
                        Q2[tail2]=s;
                        tail2=(tail2+1)%MaxSize;
                    }
                }
                 for(int i=0;i<4;i++){
                    s = t;
                    s.a[i]--;
                    if(s.a[i]<1) s.a[i]=9;
                    ans = trans(s);
                    if(visit[ans]==1) return step1+step2;
                    if(!visit[ans]){
                        visit[ans] = 2;
                        s.step = step2;
                        Q2[tail2]=s;
                        tail2=(tail2+1)%MaxSize;
                    }
                }
                for(int i=0;i<3;i++){
                    s = t;
                    swap(s.a[i],s.a[i+1]);
                    ans = trans(s);
                    if(visit[ans]==1) return step1+step2;
                    if(!visit[ans]){
                        visit[ans] = 2;
                        s.step = step2;
                        Q2[tail2]=s;
                        tail2=(tail2+1)%MaxSize;
                    }
                }
                head2 = (head2+1)%MaxSize;
            }
    }
}
void Input_and_solve(){
    char ch[5];
    scanf("%s",ch);
    for(int i=0;i<4;i++) start.a[i] = ch[i]-'0';
    scanf("%s",ch);
    for(int i=0;i<4;i++) goal.a[i] = ch[i]-'0';
    printf("%d\n",BFS());
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        Input_and_solve();
    }
}
//如有错误,还请留言指出

转载于:https://www.cnblogs.com/Pretty9/p/7347722.html


http://www.niftyadmin.cn/n/4610647.html

相关文章

Cocopods安装和升级备忘录

2019独角兽企业重金招聘Python工程师标准>>> 这是两个多月前写在mac 备忘录上的一个备忘文档&#xff0c;现在分享出来&#xff0c;希望对新手或者需要的人有帮助 cocopods安装 相关概念解释 Homebrew(brew) Homebrew(brew) 是macOS上的包管理器,安装命令行工具&…

layui table中 field参数

一、 layui table中 field参数是个对象&#xff0c;点不出来 解决&#xff1a; 在实体类中增加get方法 二、field参数判断后台的值进行显示

crontab文件的真实位置

Linux在相应用户下&#xff0c;用crontab &#xff0d;l 命令可以查看该用户定时执行的任务&#xff0c;-e可以编辑&#xff0c;但是其真实文件在哪儿呢&#xff1f;&#xff1f;以CentOS为例&#xff0c;其真实的位置在&#xff1a;/var/spool/cron下面&#xff0c;有执行定时…

关于Oracle中sysoper这个系统权限的问题

我们都知道Oracle数据库安装完之后。默认的会有这样几个系统角色或权限。nomal,sysdba,sysoper等等&#xff0c;之前每次登录Oracle的时候。都是直接以conn / as sysdba 的身份登录的。可是一直都不知道sysoper是用来干嘛的&#xff0c;仅仅知道是个系统操作员。 然后&#xff…

HBase 1、HBase介绍和工作原理

HBase是一个分布式的、面向列的开源数据库&#xff0c;该技术来源于 Fay Chang 所撰写的Google论文“Bigtable&#xff1a;一个结构化数据的分布式存储系统”。就像Bigtable利用了Google文件系统&#xff08;File System&#xff09;所提供的分布式数据存储一样&#xff0c;HBa…

freemark里面设置一个单选框,根据后台的值进行回选

freemark里面设置一个单选框&#xff0c;根据后台的值进行回显 <input type"radio" name"provisional" <#if sopInfo.provisional false>checked</#if> value"0" class"layui-input" title"否"><in…

Linux set命令详解:开启,关闭shell功能属性

set是一个shell内部命令&#xff0c;用于开启或关闭shell功能属性&#xff0c;如果什么都不加&#xff0c;则直接显示用户自定义变量和环境变量语法&#xff1a;set [选项...]选项&#xff1a;-f&#xff1a;禁用通配符f&#xff1a;启用通配符-u&#xff1a;如果脚本中有未设置…

【BZOJ 1997】[Hnoi2010]Planar

Description Input Output 找到哈密尔顿环之后找到不在哈密尔顿环上的边这些边如果同时在里面相交那他们同时在外面也相交&#xff0c;所以只能一外一内&#xff0c;这就变成了2-SAT&#xff0c;判一下就好了平面图性质 边数<3*n-61 #include<cstdio>2 #include<cs…