【C】dfs/bfs--9度OJ四题

这里写图片描述

#include<stdio.h>
#include<vector>
#include<string>
#include<algorithm>
#include<queue>
using namespace std;
int g[51][51][51];
int mark[51][51][51]={0};
int l[][3]={1,0,0,
            -1,0,0,
            0,1,0,
            0,-1,0,
            0,0,1,
            0,0,-1};
struct INFO{
    int x,y,z;
    int t;
};
bool value(int A,int B,int C,int x,int y,int z){
    if(x>=0&&x<A&&y>=0&&y<B&&z>=0&&z<C) return true;
    else return false;
}
int bfs(int A,int B,int C,int T){
    INFO s;
    s.x=0;s.y=0;s.z=0;s.t=0;//将起始改为111
    mark[s.x][s.y][s.z]=1;
    queue<INFO> q;
    q.push(s);
    while(!q.empty()){
        INFO t=q.front();
        q.pop();
        for(int i=0;i<6;i++){
            int nx=t.x+l[i][0];
            int ny=t.y+l[i][1];
            int nz=t.z+l[i][2];
            if(!value(A,B,C,nx,ny,nz)) continue;
            if(g[nx][ny][nz]==1) continue;
            if(mark[nx][ny][nz]==1) continue;
            INFO tmp;
            tmp.x=nx;tmp.y=ny;tmp.z=nz;
            tmp.t=t.t+1;
            q.push(tmp);
            mark[nx][ny][nz]=1;
            if(nx==A-1&&ny==B-1&&nz==C-1) return tmp.t;
        }   
    }
    return -1;
}


        /*int x=s.x,y=s.y,z=t.z;
        if(x==A-1&&y==B-1&&z==C-1){
            return t.t;
        }
        INFO p;
        p.x=x-1;p.y=y;p.z=z;
        if(value(A,B,C,p.x,p.y,p.z)&&g[p.x][p.y][p.z]==0&&mark[p.x][p.y][p.z]==0){
            p.t=t.t+1;
            if(p.x==A-1&&p.y==B-1&&p.z==C-1){
                return p.t;
            }
            //if(p.t<=T){
                mark[p.x][p.y][p.z]=1;
                q.push(p);
            //}
        }
        p.x=x+1;p.y=y;p.z=z;
        if(value(A,B,C,p.x,p.y,p.z)&&g[p.x][p.y][p.z]==0&&mark[p.x][p.y][p.z]==0){
            p.t=t.t+1;
            if(p.x==A-1&&p.y==B-1&&p.z==C-1){
                return p.t;
            }
            //if(p.t<=T){
                mark[p.x][p.y][p.z]=1;
                q.push(p);
            //}
        }
        p.x=x;p.y=y-1;p.z=z;
        if(value(A,B,C,p.x,p.y,p.z)&&g[p.x][p.y][p.z]==0&&mark[p.x][p.y][p.z]==0){
            p.t=t.t+1;
            if(p.x==A-1&&p.y==B-1&&p.z==C-1){
                return p.t;
            }
            //if(p.t<=T){
                mark[p.x][p.y][p.z]=1;
                q.push(p);
            //}
        }
        p.x=x;p.y=y+1;p.z=z;
        if(value(A,B,C,p.x,p.y,p.z)&&g[p.x][p.y][p.z]==0&&mark[p.x][p.y][p.z]==0){
            p.t=t.t+1;
            if(p.x==A-1&&p.y==B-1&&p.z==C-1){
                return p.t;
            }
            //if(p.t<=T){
                mark[p.x][p.y][p.z]=1;
                q.push(p);
            //}
        }
        p.x=x;p.y=y;p.z=z-1;
        if(value(A,B,C,p.x,p.y,p.z)&&g[p.x][p.y][p.z]==0&&mark[p.x][p.y][p.z]==0){
            p.t=t.t+1;
            if(p.x==A-1&&p.y==B-1&&p.z==C-1){
                return p.t;
            }
            //if(p.t<=T){
                mark[p.x][p.y][p.z]=1;
                q.push(p);
            //}
        }
        p.x=x;p.y=y;p.z=z+1;
        if(value(A,B,C,p.x,p.y,p.z)&&g[p.x][p.y][p.z]==0&&mark[p.x][p.y][p.z]==0){
            p.t=t.t+1;
            if(p.x==A-1&&p.y==B-1&&p.z==C-1){
                return p.t;
            }
            //if(p.t<=T){
                mark[p.x][p.y][p.z]=1;
                q.push(p);
            //}
        }
    }
    return -1;
}*/


int main(){
    int n;
    scanf("%d",&n);
    while(n--){
        //fill(g[0][0],g[0][0]+51*51*51,1);//默认都是墙
        fill(mark[0][0],mark[0][0]+51*51*51,0);
        int A,B,C,T;
        scanf("%d%d%d%d",&A,&B,&C,&T);
        for(int i=0;i<A;i++){
            for(int j=0;j<B;j++){
                for(int k=0;k<C;k++){
                    scanf("%d",&g[i][j][k]);
                }
            }
        }
        int minT=bfs(A,B,C,T);
        if(minT<=T) printf("%d\n",minT);
        else printf("-1\n");

    }
}
/*1
3 3 4 20
0 1 1 1
0 0 1 1
0 1 1 1
1 1 1 1
1 0 0 1
0 1 1 1
0 0 0 0
0 1 1 0
0 1 1 0
》》
11*/

Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)……

这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带锁的门,钥匙藏在地牢另外的某些地方。刚开始Ignatius被关在(sx,sy)的位置,离开地牢的门在(ex,ey)的位置。Ignatius每分钟只能从一个坐标走到相邻四个坐标中的其中一个。魔王每t分钟回地牢视察一次,若发现Ignatius不在原位置便把他拎回去。经过若干次的尝试,Ignatius已画出整个地牢的地图。现在请你帮他计算能否再次成功逃亡。只要在魔王下次视察之前走到出口就算离开地牢,如果魔王回来的时候刚好走到出口或还未到出口都算逃亡失败。

输入描述:
每组测试数据的第一行有三个整数n,m,t(2<=n,m<=20,t>0)。接下来的n行m列为地牢的地图,其中包括:
. 代表路
* 代表墙
@ 代表Ignatius的起始位置
^ 代表地牢的出口
A-J 代表带锁的门,对应的钥匙分别为a-j a-j 代表钥匙,对应的门分别为A-J 每组测试数据之间有一个空行。

输出描述:
针对每组测试数据,如果可以成功逃亡,请输出需要多少分钟才能离开,如果不能则输出-1。

示例1

输入

4 5 17
@A.B.
a*.*.
..^
c..b*

4 5 16
@A.B.
a*.*.
..^
c..b*

输出

16
-1

#include<stdio.h>
#include<queue>
using namespace std;
int n,m,tx,ty,T;
char g[22][22];
int vis[22][22][1200]={0};
int l[][2]={1,0,
            -1,0,
            0,1,
            0,-1};
struct Node{
    int x,y;
    int deep;
    int key;
    Node(int x,int y,int deep,int key):x(x),y(y),deep(deep),key(key) {}
};
int bfs(int x,int y){
    queue<Node> q;
    q.push(Node(x,y,0,0));
    vis[x][y][0]=1;
    while(!q.empty()){
        Node t=q.front();
        q.pop();
        if(t.deep>=T) return -1;
        if(t.x==tx&&t.y==ty) return t.deep;
        for(int i=0;i<4;i++){
            int nx=t.x+l[i][0];
            int ny=t.y+l[i][1];
            if(nx<0||ny<0||nx>=n||ny>=m) continue;
            if(g[nx][ny]=='*') continue;
            int key=t.key;
            if(g[nx][ny]>='a'&&g[nx][ny]<='j') key=key|(1<<(g[nx][ny]-'a'));
            if(g[nx][ny]>='A'&&g[nx][ny]<='J'&&(key&(1<<(g[nx][ny]-'A')))==0) continue;
            if(vis[nx][ny][key]==0){
                vis[nx][ny][key]=1;
                q.push(Node(nx,ny,t.deep+1,key));
            }
        }
    }
    return -1;
}
int main(){
    int x,y;
    while(scanf("%d%d%d",&n,&m,&T)!=EOF){
        for(int i=0;i<n;i++){
            getchar();
            for(int j=0;j<m;j++){
                scanf("%c",&g[i][j]);
                if(g[i][j]=='@'){
                    x=i;y=j;
                }
                else if(g[i][j]=='^'){
                    tx=i;ty=j;
                }
            }
        }
        printf("%d\n",bfs(x,y));
    }
}

这里写图片描述

#include<stdio.h>
#include<queue>
using namespace std;
int mark[101][101][101];
struct INFO{
    int a,b,c;
    int t;
};
void AtoB(int &a,int sa,int &b,int sb){
    if(sb-b>=a){
        b+=a;
        a=0;
    }
    else{
        a=a-(sb-b);
        b=sb;
    }
}
int bfs(int s,int n,int m){
    INFO p;
    p.a=s;p.b=0;p.c=0;p.t=0;
    queue<INFO> q;
    q.push(p);
    while(!q.empty()){
        INFO t=q.front();
        q.pop();
        int na=t.a,nb=t.b,nc=t.c;
        AtoB(na,s,nb,n);
        if(mark[na][nb][nc]==0){
            mark[na][nb][nc]=1;
            if(na==s/2&&nb==s/2) return t.t+1;
            if(na==s/2&&nc==s/2) return t.t+1;
            if(nc==s/2&&nb==s/2) return t.t+1;
            INFO tmp;
            tmp.a=na;tmp.b=nb;tmp.c=nc;tmp.t=t.t+1;
            q.push(tmp);
        }
        na=t.a,nb=t.b,nc=t.c;
        AtoB(nb,n,na,s);
        if(mark[na][nb][nc]==0){
            mark[na][nb][nc]=1;
            if(na==s/2&&nb==s/2) return t.t+1;
            if(na==s/2&&nc==s/2) return t.t+1;
            if(nc==s/2&&nb==s/2) return t.t+1;
            INFO tmp;
            tmp.a=na;tmp.b=nb;tmp.c=nc;tmp.t=t.t+1;
            q.push(tmp);
        }
        na=t.a,nb=t.b,nc=t.c;
        AtoB(nb,n,nc,m);
        if(mark[na][nb][nc]==0){
            mark[na][nb][nc]=1;
            if(na==s/2&&nb==s/2) return t.t+1;
            if(na==s/2&&nc==s/2) return t.t+1;
            if(nc==s/2&&nb==s/2) return t.t+1;
            INFO tmp;
            tmp.a=na;tmp.b=nb;tmp.c=nc;tmp.t=t.t+1;
            q.push(tmp);
        }
        na=t.a,nb=t.b,nc=t.c;
        AtoB(nc,m,nb,n);
        if(mark[na][nb][nc]==0){
            mark[na][nb][nc]=1;
            if(na==s/2&&nb==s/2) return t.t+1;
            if(na==s/2&&nc==s/2) return t.t+1;
            if(nc==s/2&&nb==s/2) return t.t+1;
            INFO tmp;
            tmp.a=na;tmp.b=nb;tmp.c=nc;tmp.t=t.t+1;
            q.push(tmp);
        }
        na=t.a,nb=t.b,nc=t.c;
        AtoB(nc,m,na,s);
        if(mark[na][nb][nc]==0){
            mark[na][nb][nc]=1;
            if(na==s/2&&nb==s/2) return t.t+1;
            if(na==s/2&&nc==s/2) return t.t+1;
            if(nc==s/2&&nb==s/2) return t.t+1;
            INFO tmp;
            tmp.a=na;tmp.b=nb;tmp.c=nc;tmp.t=t.t+1;
            q.push(tmp);
        }
        na=t.a,nb=t.b,nc=t.c;
        AtoB(na,s,nc,m);
        if(mark[na][nb][nc]==0){
            mark[na][nb][nc]=1;
            if(na==s/2&&nb==s/2) return t.t+1;
            if(na==s/2&&nc==s/2) return t.t+1;
            if(nc==s/2&&nb==s/2) return t.t+1;
            INFO tmp;
            tmp.a=na;tmp.b=nb;tmp.c=nc;tmp.t=t.t+1;
            q.push(tmp);
        }
    }
    return -1;
}
int main(){
    int s,n,m;
    scanf("%d%d%d",&s,&n,&m);
    while(s!=0||n!=0||m!=0){
        fill(mark[0][0],mark[0][0]+101*101*101,0);
        if(s%2==1) printf("No\n");
        else if(s==0) printf("0\n");
        else{
            int t=bfs(s,n,m);
            printf("%d\n",t);
        }
        scanf("%d%d%d",&s,&n,&m);
    }
}
/*
7 4 3
4 1 3
0 0 0
》》
NO
3
*/

这里写图片描述
这里写图片描述

#include<stdio.h>
#include<queue>
#include<vector>
#include<math.h>
using namespace std;
int n,m;
char g1[110][110];
int mark[110][110];
int l[][2]={1,0,
           1,1,
           1,-1,
           -1,0,
           -1,1,
           -1,-1,
            0,1,
            0,-1};
void dfs(int x,int y){
    for(int i=0;i<8;i++){
        int nx=x+l[i][0];
        int ny=y+l[i][1];
        if(nx<0||nx>=n||ny<0||ny>=m) continue;
        if(mark[nx][ny]==1) continue;
        if(g1[nx][ny]!='@') continue;
        mark[nx][ny]=1;
        dfs(nx,ny);
    }
    return;
}
int main(){
    while(scanf("%d%d",&n,&m)!=EOF){
        getchar();
        if(n==0&&m==0) return 0;
        fill(g1[0],g1[0]+110*110,'*');
        fill(mark[0],mark[0]+110*110,0);
        for(int i=0;i<n;i++){   
            for(int j=0;j<m;j++){
                scanf("%c",&g1[i][j]);
            }
            getchar();
        }
        /*printf("%d %d\n",n,m);
        for(int i=0;i<n;i++){   
            for(int j=0;j<m;j++){
                printf("%cLLL   ",g1[i][j]);
            }
            printf("\n");
        }*/
        int num=0;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(mark[i][j]==0&&g1[i][j]=='@'){
                    dfs(i,j);
                    num++;
                }
            }
        }
        printf("%d\n",num);
    }
    return 0;
}
/*
1 1
*
3 5
*@*@*
**@**
*@*@*
1 8
@@****@*
5 5 
****@
*@@*@
*@**@
@@@*@
@@**@
0 0
》》
0
1
2
2
*/

这里写图片描述
这里写图片描述

#include<stdio.h>
#include<queue>
#include<vector>
#include<math.h>
using namespace std;
struct INFO{
    int x,y;
    int t;
};
int l[][2]={1,0,
            -1,0,
            0,1,
            0,-1};
int n,m,T;
char g[8][8];
int mark[8][8]={0};
bool dfs(int x,int y,int t){
    if(g[x][y]=='D'&&t==T) return true;
    for(int i=0;i<4;i++){
        int nx=x+l[i][0];
        int ny=y+l[i][1];
        if(nx>=n||nx<0||ny>=m||ny<0) continue;
        if(mark[nx][ny]==1) continue;
        if(g[nx][ny]=='X') continue;
        mark[nx][ny]=1;
        if(dfs(nx,ny,t+1)) return true;//可以提前结束
        mark[nx][ny]=0;
    }
    return false;
}
int main(){
    while(scanf("%d%d%d",&n,&m,&T)!=EOF){
        if(n==0&&m==0&&T==0) break;
        fill(g[0],g[0]+64,'X');
        fill(mark[0],mark[0]+64,0);
        getchar();
        int bi,bj;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                scanf("%c",&g[i][j]);
                if(g[i][j]=='S'){
                    bi=i;bj=j;
                }
            }
            getchar();
        }
        if(dfs(bi,bj,0)) printf("YES\n");
        else printf("NO\n");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值