BFS专题练习

目录

A. 抓住那只牛

Format

Input

Output

Samples

输入数据 1

输出数据 1

B. 骑士移动

Format

Input

Output

Samples

输入数据 1

输出数据 1

C. 细胞 

Description

Format

Input

Output

Samples

输入数据 1

输出数据 1

D. 营救铁达尼号 

Description

Format

Input

Output

Samples

输入数据 1

输出数据 1

E. 迷宫游戏之打印路径1

Description

Format

Input

Output

Samples

输入数据 1

输出数据 1

F. 迷宫游戏之打印路径2

Description

Format

Input

Output

Samples

输入数据 1

输出数据 1

G. 矩形距离

Description

Format

Input

Output

Samples

输入数据 1

输出数据 1

H. 迷宫游戏1

Description

Format

Input

Output

Samples

输入数据 1

输出数据 1

I. 迷宫游戏4

Description

Format

Input

Output

Samples

输入数据 1

输出数据 1

Limitation

J. 迷宫游戏5

Description

Format

Input

Output

Samples


A. 抓住那只牛

农夫约翰被通知,他的一只奶牛逃逸了!所以他决定,马上出发,尽快把那只奶牛抓回来,他们都站在数轴上.

约翰在N(0≤N≤100000)处,奶牛在K(0≤K≤100000)处.

约翰有两种办法移动,步行和瞬移:步行每秒种可以让约翰从x处走到x+1或x-1处;而瞬移则可让他在1秒内从x处消失,在2x处出现.

然而那只逃逸的奶牛,悲剧地没有发现自己的处境多么糟糕,正站在那儿一动不动.

那么,约翰需要多少时间抓住那只牛呢?

Format

Input

仅有两个整数N和K.

Output

最短的时间.

Samples

输入数据 1

5 17

Copy

输出数据 1

4

如果n大于等于k,那么只能选择一个一个减过去,直接输出n-k

其他的情况就是当*2之后比范围大之后就可以不管了 

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n,k;
unordered_map<int,int>d;
int a[3]={1,-1};
int main(){
    cin>>n>>k;
    if(n>=k){
        cout<<n-k;
        return 0;
    }
    queue<int>q;
    q.push(n);
    while(q.size()){
        int p=q.front();
        q.pop();
        for(int i=0;i<3;i++){
            int xz;
            if(i!=2)xz=p+a[i];
            else xz=p*2;
            if(xz==k){
                cout<<d[p]+1;
                return 0;
            }
            if(!d[xz]&&xz!=n&&xz<=100000){
                d[xz]=d[p]+1;
                q.push(xz);
            }
        }
    }
    return 0;
}

B. 骑士移动

贝茜和表妹各有一颗棋子。棋子每次移一步,且棋子只能往如图所示的八个方向移动。 

比赛的规则很简单,两个人需要从起点将棋子移到终点,谁能花最少的步数从起点走到终点,就是赢家。

为了确保能赢表妹,贝茜希望每次都能算出最少的步数,你能帮助她么,棋盘大小为8*8的。

Format

Input

输入起点和终点,用一个空格隔开。(确保起点一定能走到终点)

起点及终点均有横纵坐标

其中横坐标用字母来表示,a代表第一行,b代表第二行

纵坐标用数字来表示

Output

输入最少的步数。

Samples

输入数据 1

a1 b2

Copy

输出数据 1

4

Copy

Hint

a1代表第一行第一列

b2代表第二行第二列

从(1,1)跳到(2,2)

从1---- >2---- >3---- >4---- >5 

有点像马的遍历,给出起点和终点然后按马的方式走八个方向就行,如果一开始起点就是终点则直接输出0 

#include<bits/stdc++.h>
using namespace std;
#define ll long long
string x,y;
queue<pair<int,int>>q;
int v[10][10];
int dx[]={-2,-2,-1,-1,1,1,2,2};
int dy[]={-1,1,-2,2,-2,2,-1,1};
int main(){
    cin>>x>>y;
    int ax=x[0]-'a'+1,ay=x[1]-'0';
    int bx=y[0]-'a'+1,by=y[1]-'0';
    if(ax==bx&&ay==by){
        cout<<0;
    }
    else{
        q.push({ax,ay});
        while(q.size()){
            auto p=q.front();
            int px=p.first,py=p.second;
            q.pop();
            for(int i=0;i<8;i++){
                int ex=px+dx[i];
                int ey=py+dy[i];
                if(ex==bx&&ey==by){
                    // cout<<px<<' '<<py<<" "<<"\n";
                    cout<<v[px][py]+1;
                    return 0;
                }
                if(ex>=1&&ex<=8&&ey>=1&&ey<=8&&!v[ex][ey]){
                    q.push({ex,ey});
                    v[ex][ey]=v[px][py]+1;
                }
            }
        }
    }
    return 0;
}

C. 细胞 

Description

一矩形阵列由数字0到9组成,数字1到9代表细胞,

细胞的定义为沿细胞数字上下左右还是细胞数字则为同一细胞,

求给定矩形阵列的细胞个数。

Format

Input

整数m,n(m行,n列)

1<=N,M<=100

Output

细胞的个数

Samples

输入数据 1

4 10
0234500067
1034560500
2045600671
0000000089

Copy

输出数据 1

4

找联通块的数量,遍历找到一个不为0的就bfs将一个联通块全部归零即可 

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n,m;
char a[105][105];
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};
void solve(int x,int y){
    queue<pair<int,int>>q;
    q.push({x,y});
    while(q.size()){
        auto p=q.front();
        q.pop();
        int px=p.first,py=p.second;
        for(int i=0;i<4;i++){
            int sx=px+dx[i];
            int sy=py+dy[i];
            if(sx>=0&&sx<n&&sy>=0&&sy<m&&a[sx][sy]!='0'){
                a[sx][sy]='0';
                q.push({sx,sy});
            }
        }
    }
}
int main(){
    cin>>n>>m;
    int cnt=0;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>a[i][j];
        }
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(a[i][j]!='0'){
                solve(i,j);
                cnt++;
            }
        }
    }
    cout<<cnt;
    return 0;
}

D. 营救铁达尼号 

Description

铁塔尼号遇险了!他发出了求救信号。

距离最近的哥伦比亚号收到了讯息,时间就是生命,必须尽快赶到那里。通过侦测,哥伦比亚号获取了一张海洋图。

这张图将海洋部分分化成n*n个比较小的单位,其中用1标明的是陆地,用0标明是海洋。

船只能从一个格子,移到相邻的四个格子。为了尽快赶到出事地点,哥伦比亚号最少需要走多远的距离。

Format

Input

第一行为n,下面是一个n*n的0,1矩阵,表示海洋地图

最后一行为四个小于n的整数,分别表示哥伦比亚号和铁塔尼号的位置。

N<=1000

Output

哥伦比亚号到铁塔尼号的最短距离,答案精确到整数。

Samples

输入数据 1

3
001
101
100
1 1 3 3

Copy

输出数据 1

4

走迷宫板子题 

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n,ax,ay,bx,by;
char a[1005][1005];
int d[1005][1005];
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};
void solve(int x,int y){
    queue<pair<int,int>>q;
    q.push({x,y});
    while(q.size()){
        auto p=q.front();
        q.pop();
        int px=p.first,py=p.second;
        for(int i=0;i<4;i++){
            int sx=px+dx[i];
            int sy=py+dy[i];
            if(sx==bx&&sy==by){
                cout<<d[px][py]+1;
                return;
            }
            if(sx>=1&&sx<=n&&sy>=1&&sy<=n&&a[sx][sy]=='0'&&!d[sx][sy]){
                d[sx][sy]=d[px][py]+1;
                q.push({sx,sy});
            }
        }
    }
}
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            cin>>a[i][j];
        }
    }
    cin>>ax>>ay>>bx>>by;
    if(ax==bx&&ay==by)cout<<0;
    else solve(ax,ay);
    return 0;
}

E. 迷宫游戏之打印路径1

Description

下图给出了一个迷宫的平面图,其中标记为1 的为障碍,标记为0 的为可以通行的地方。

010000

000100

001001

110000

迷宫的入口为左上角,出口为右下角

在迷宫中,只能从一个位置走到这个它的上、下、左、右四个方向之一。

对于上面的迷宫,从入口开始,可以按DRRURRDDDR 的顺序通过迷宫,一共10 步。

其中D、U、L、R 分别表示向下、向上、向左、向右走。

对于下面这个更复杂的迷宫(30 行50 列),

请找出一种通过迷宫的方式,其使用的步数最少,在步数最少的前提下,请找出字典序最小的一个作为答案。

请注意在字典序中D<L<R<U。

Format

Input

给出一个30行50列的字符矩形

Output

如题

Samples

输入数据 1

01010101001011001001010110010110100100001000101010
00001000100000101010010000100000001001100110100101
01111011010010001000001101001011100011000000010000
01000000001010100011010000101000001010101011001011
00011111000000101000010010100010100000101100000000
11001000110101000010101100011010011010101011110111
00011011010101001001001010000001000101001110000000
10100000101000100110101010111110011000010000111010
00111000001010100001100010000001000101001100001001
11000110100001110010001001010101010101010001101000
00010000100100000101001010101110100010101010000101
11100100101001001000010000010101010100100100010100
00000010000000101011001111010001100000101010100011
10101010011100001000011000010110011110110100001000
10101010100001101010100101000010100000111011101001
10000000101100010000101100101101001011100000000100
10101001000000010100100001000100000100011110101001
00101001010101101001010100011010101101110000110101
11001010000100001100000010100101000001000111000010
00001000110000110101101000000100101001001000011101
10100101000101000000001110110010110101101010100001
00101000010000110101010000100010001001000100010101
10100001000110010001000010101001010101011111010010
00000100101000000110010100101001000001000000000010
11010000001001110111001001000011101001011011101000
00000110100010001000100000001000011101000000110011
10101000101000100010001111100010101001010000001000
10000010100101001010110000000100101010001011101000
00111100001000010000000110111000000001000000001011
10000001100111010111010001000110111010101101111000

Copy

输出数据 1

DDDDRRURRRRRRDRRRRDDDLDDRDDDDDDDDDDDDRDDRRRURRUURRDDDDRDRRRRRRDRRURRDDDRRRRUURUUUUUUULULLUUUURRRRUULLLUUUULLUUULUURRURRURURRRDDRRRRRDDRRDDLLLDDRRDDRDDLDDDLLDDLLLDLDDDLDDRRRRRRRRRDDDDDDRR

Copy

按字典序最小的边走边标记,最先走到的就是答案 

#include<bits/stdc++.h>
using namespace std;
#define ll long long
char a[35][55];
int d[1005][1005];
int dx[]={1,0,0,-1};
int dy[]={0,-1,1,0};
map<pair<int,int>,string>m;
/*
d l r u
下 左 右 上
*/
void solve(int x,int y){
    queue<pair<int,int>>q;
    q.push({x,y});
    while(q.size()){
        auto p=q.front();
        q.pop();
        int px=p.first,py=p.second;
        for(int i=0;i<4;i++){
            int sx=px+dx[i];
            int sy=py+dy[i];
            if(sx>=1&&sx<=30&&sy>=1&&sy<=50&&a[sx][sy]=='0'&&!d[sx][sy]){
                d[sx][sy]=d[px][py]+1;
                string xxs;
                if(i==0)xxs="D";
                else if(i==1)xxs="L";
                else if(i==2)xxs="R";
                else xxs="U";
                m[{sx,sy}]=m[{px,py}]+xxs;
                q.push({sx,sy});
            }
            if(sx==30&&sy==50){
                cout<<m[{sx,sy}];
                return;
            }
        }
    }
}
int main(){
    for(int i=1;i<=30;i++){
        for(int j=1;j<=50;j++){
            cin>>a[i][j];
        }
    }
    solve(1,1);
    return 0;
}

F. 迷宫游戏之打印路径2

Description

下图给出了一个迷宫的平面图,其中标记为1 的为障碍,标记为0 的为可以通行的地方。

010000

000100

001001

110000

迷宫的入口为左上角,出口为右下角

在迷宫中,只能从一个位置走到这个它的上、下、左、右四个方向之一。

对于上面的迷宫,从入口开始,可以按DRRURRDDDR 的顺序通过迷宫,一共10 步。

其中D、U、L、R 分别表示向下、向上、向左、向右走。

对于下面这个更复杂的迷宫(1000 行1000 列),

请找出一种通过迷宫的方式,其使用的步数最少,在步数最少的前提下,请找出字典序最小的一个作为答案。

请注意在字典序中D<L<R<U。

Format

Input

给出一个1000行1000列的字符矩形

Output

如题

Samples

输入数据 1

01010101001011001001010110010110100100001000101010
00001000100000101010010000100000001001100110100101
01111011010010001000001101001011100011000000010000
01000000001010100011010000101000001010101011001011
00011111000000101000010010100010100000101100000000
11001000110101000010101100011010011010101011110111
00011011010101001001001010000001000101001110000000
10100000101000100110101010111110011000010000111010
00111000001010100001100010000001000101001100001001
11000110100001110010001001010101010101010001101000
00010000100100000101001010101110100010101010000101
11100100101001001000010000010101010100100100010100
00000010000000101011001111010001100000101010100011
10101010011100001000011000010110011110110100001000
10101010100001101010100101000010100000111011101001
10000000101100010000101100101101001011100000000100
10101001000000010100100001000100000100011110101001
00101001010101101001010100011010101101110000110101
11001010000100001100000010100101000001000111000010
00001000110000110101101000000100101001001000011101
10100101000101000000001110110010110101101010100001
00101000010000110101010000100010001001000100010101
10100001000110010001000010101001010101011111010010
00000100101000000110010100101001000001000000000010
11010000001001110111001001000011101001011011101000
00000110100010001000100000001000011101000000110011
10101000101000100010001111100010101001010000001000
10000010100101001010110000000100101010001011101000
00111100001000010000000110111000000001000000001011
10000001100111010111010001000110111010101101111000

Copy

输出数据 1

DDDDRRURRRRRRDRRRRDDDLDDRDDDDDDDDDDDDRDDRR

先标记横纵坐标,最后再确定上下左右方向即可,别和我一样搞错方向就行

bfs终点到起点,顺序找答案

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n=1000;
char a[1005][1005];
int ex[1005][1005];//记录下一个的横坐标
int ey[1005][1005];//记录下一个的纵坐标
int dx[]={1,0,0,-1};
int dy[]={0,-1,1,0};
void solve(){
    queue<pair<int,int>>q;
    q.push({1000,1000});
    while(q.size()){
        auto p=q.front();
        q.pop();
        for(int i=0;i<4;i++){
            int sx=p.first+dx[i];
            int sy=p.second+dy[i];
            // cout<<sx<<' '<<sy<<' '<<a[sx][sy]<<"\n";
            if(sx>=1&&sx<=n&&sy>=1&&sy<=n&&a[sx][sy]=='0'&&!ex[sx][sy]&&!ey[sx][sy]){
                // cout<<sx<<' '<<sy<<' '<<a[sx][sy]<<"\n";
                q.push({sx,sy});
                ex[sx][sy]=p.first;
                ey[sx][sy]=p.second;
            }
        }
    }
}
int main(){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            cin>>a[i][j];
            // a[i][j]='0';
        }
    }
    ex[1000][1000]=ey[1000][1000]=1000;
    solve();
    int x,y;
    for(int l=1,r=1;l!=1000||r!=1000;l=x,r=y){
        if(l<1||r<1||l>1000||r>1000)break;
        x=ex[l][r];
        y=ey[l][r];
        char xxs;
        if(x-l==1)xxs='D';
        else if(r-y==1)xxs='L';
        else if(r-y==-1)xxs='R';
        else if(x-l==-1)xxs='U';
        cout<<xxs;
        // cout<<l<<' '<<r<<" "<<x<<' '<<y<<" "<<xxs<<"\n";
        // cout<<x<<' '<<y<<"\n";
    }
    return 0;
}

bfs起点到终点,逆序找答案

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n=1000;
char a[1005][1005];
int ex[1005][1005];
int ey[1005][1005];
int dx[]={1,0,0,-1};
int dy[]={0,-1,1,0};
char ppt[1000005];
void solve(){
    queue<pair<int,int>>q;
    q.push({1,1});
    while(q.size()){
        auto p=q.front();
        q.pop();
        for(int i=0;i<4;i++){
            int sx=p.first+dx[i];
            int sy=p.second+dy[i];
            // cout<<sx<<' '<<sy<<' '<<a[sx][sy]<<"\n";
            if(sx>=1&&sx<=n&&sy>=1&&sy<=n&&a[sx][sy]=='0'&&!ex[sx][sy]&&!ey[sx][sy]){
                // cout<<sx<<' '<<sy<<' '<<a[sx][sy]<<"\n";
                q.push({sx,sy});
                ex[sx][sy]=p.first;
                ey[sx][sy]=p.second;
            }
        }
    }
}
int main(){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            cin>>a[i][j];
            // a[i][j]='0';
        }
    }
    ex[1][1]=ey[1][1]=1;
    solve();
    int cnt=0;
    int x,y;
    for(int l=1000,r=1000;l!=1||r!=1;l=x,r=y){
        x=ex[l][r];
        y=ey[l][r];
        char xxs;
        if(x-l==-1)xxs='D';
        else if(r-y==-1)xxs='L';
        else if(r-y==1)xxs='R';
        else if(x-l==1)xxs='U';
        ppt[cnt++]=xxs;
        // cout<<l<<' '<<r<<" "<<x<<' '<<y<<" "<<xxs<<"\n";
        // cout<<x<<' '<<y<<"\n";
    }
    for(int i=cnt-1;i>=0;i--)cout<<ppt[i];
    return 0;
}

G. 矩形距离

Description

给你一个N*M的矩形,每个元素不是0就是1

输出离每个元素距离最近的1的距离

距离定义为D(aij,akl)=abs(i-k)+abs(j-l)。

Format

Input

第一行给出N,M 接下来N行M列描述这个矩形

N,M<=1000

Output

如题

Samples

输入数据 1

3 4
0001
0011
0110

Copy

输出数据 1

3 2 1 0
2 1 0 0
1 0 0 1

记录下来右多少个1标记,全部加到队列里去,然后跑一遍bfs标记所有 

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n,m,cnt;
char a[1005][1005];
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};
queue<pair<int,int>>q;
int d[1005][1005];
void solve(){
    while(q.size()){
        auto p=q.front();
        q.pop();
        int px=p.first,py=p.second;
        for(int i=0;i<4;i++){
            int sx=px+dx[i];
            int sy=py+dy[i];
            if(sx>=0&&sx<n&&sy>=0&&sy<m&&!d[sx][sy]){
                q.push({sx,sy});
                d[sx][sy]=d[px][py]+1;
                cnt++;
            }
            if(cnt==n*m)return;
        }
    }
}
int main(){
    cin>>n>>m;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>a[i][j];
            if(a[i][j]=='1'){
                q.push({i,j});
                cnt++;
                d[i][j]=1;
            }
        }
    }
    if(cnt!=n*m){
        solve();
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cout<<d[i][j]-1<<' ';
        }
        cout<<"\n";
    }
    return 0;
}

H. 迷宫游戏1

Description

迷宫的游戏,相信大家都听过,现在我们用一个n*m的矩阵表示一个迷宫,例如:

S.X.

..X.

..XD

....

其中‘S’表示起点,‘D’表示终点,‘X’表示该位置为墙,不可以走,‘.’表示可以通行。

每次只能向“上下左右”四个方向移动一步。

你的任务是判断在x步内(小于等于x),能否从起点走到终点。

Format

Input

第一行输入三个数n m x,分别表示迷宫的尺寸和步数。(1 < n,m < 7; 0 < x < 50)

接下来输入一个n*m的矩阵,描述迷宫的状态。

Output

判断是否能在x步内从起点走到终点,如果可以,输出“YES”,否则输出“NO”。

Samples

输入数据 1

3 4 5
S.X.
..X.
...D

Copy

输出数据 1

YES

标记x步内能走到的点,然后判断是否标记即可 

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n,m,x;
char a[10][10];
int sx,sy,ex,ey;
int d[10][10];
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};
void bfs(){
    queue<pair<int,int>>q;
    q.push({sx,sy});
    while(q.size()){
        auto p=q.front();
        q.pop();
        for(int i=0;i<4;i++){
            int qx=p.first+dx[i];
            int qy=p.second+dy[i];
            if(qx>=0&&qx<n&&qy>=0&&qy<m&&a[qx][qy]=='.'&&!d[qx][qy]){
                d[qx][qy]=d[p.first][p.second]+1;
                if(d[qx][qy]<=x)q.push({qx,qy});
            }
        }
    }
}
int main(){
    cin>>n>>m>>x;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>a[i][j];
            if(a[i][j]=='S')sx=i,sy=j;
            if(a[i][j]=='D')ex=i,ey=j,a[i][j]='.';
        }
    }
    d[sx][sy]=1;
    bfs();
    if(d[ex][ey])cout<<"YES";
    else cout<<"NO";
    return 0;
}

I. 迷宫游戏4

Description

迷宫的游戏,相信大家都听过,现在我们用一个n*m的矩阵表示一个迷宫,例如:

S.X.

..X.

..XD

....

其中

‘S’表示起点

‘D’表示终点

‘X’表示该位置为墙,不可以走

‘.’表示可以通行。

每次只能向“上下左右”四个方向移动一步。

你的任务是判断在x步内(小于等于x),能否从起点走到终点。

本题可能存在多个起点和多个终点,只要有一个满足条件即可。

Format

Input

第一行输入三个数n m x,分别表示迷宫的尺寸和步数。(1 < n,m < 7; 0 < x < 50)

接下来输入一个n*m的矩阵,描述迷宫的状态。

Output

判断是否能在x步内从起点走到终点,如果可以,输出“YES”,否则输出“NO”。

Samples

输入数据 1

3 4 5
S.X.
..X.
...D

Copy

输出数据 1

YES

Copy

Limitation

1s, 1024KiB for each test case.

上一题的变式,多起点多终点问题,将所有起点都加入到队列中,最后判断是否有终点被标记即可 

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n,m,x;
char a[10][10];
int sx,sy,ex,ey;
int d[10][10];
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};
queue<pair<int,int>>q;
vector<pair<int,int>>v;
void bfs(){
    while(q.size()){
        auto p=q.front();
        q.pop();
        for(int i=0;i<4;i++){
            int qx=p.first+dx[i];
            int qy=p.second+dy[i];
            if(qx>=0&&qx<n&&qy>=0&&qy<m&&a[qx][qy]=='.'&&!d[qx][qy]){
                d[qx][qy]=d[p.first][p.second]+1;
                if(d[qx][qy]<=x)q.push({qx,qy});
            }
        }
    }
}
int main(){
    cin>>n>>m>>x;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>a[i][j];
            if(a[i][j]=='S')q.push({i,j}),d[i][j]=1;
            if(a[i][j]=='D')v.push_back({i,j}),a[i][j]='.';
        }
    }
    bfs();
    for(auto i:v){
        if(d[i.first][i.second]){
            cout<<"YES";
            return 0;
        }
    }
    cout<<"NO";
    return 0;
}

J. 迷宫游戏5

Description

正所谓,“怕什么真理无穷,进一寸,有一寸的欢喜”

现在你已不满足于判断一个点能否走到另一个点了。

你希望知道从一个点到另一个点,用T秒的时间有多少种方式。

Format

Input

第1行: 3个用空格隔开的整数:N,M,T

第2..N+1行: 第i+1行为M个连续的字符,描述了迷宫第i行各点的情况,

保证字符是'.'和''中的一个,'.'表示可通过的点,''表示不可走的点

第N+2行: 4个用空格隔开的整数:R1,C1,R2,以及C2

Output

  • 第1行: 输出S,含义如题中所述

Samples

input1

4 5 6

...*.

...*.

.....

.....

1 3 1 5

output1

1

dfs搜索+剪枝,剪枝是防止越走越远浪费搜索时间,假如剩余的步数比当前点到终点之间的最短距离还少就没必要继续走下去浪费时间了 

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n,m,t;
int ans;
char a[105][105];
int sx,sy,ex,ey;
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};
void dfs(int x,int y,int step){
    // cout<<x<<' '<<y<<' '<<step<<"\n";
    if(x==ex&&y==ey&&step==t){
        ans++;
        return;
    }
    if(step+abs(x-ex)+abs(y-ey)>t)return;//如果加上两点的直线距离还走不到
    for(int i=0;i<4;i++){
        int tx=x+dx[i];
        int ty=y+dy[i];
        if(tx>=1&&tx<=n&&ty>=1&&ty<=m&&a[tx][ty]=='.'){
            dfs(tx,ty,step+1);
        }
    }
    return;
}
int main(){
    cin>>n>>m>>t;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>a[i][j];
        }
    }
    cin>>sx>>sy>>ex>>ey;
    dfs(sx,sy,0);
    cout<<ans;
    return 0;
}

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值