再解炸弹人,dfs&bfs

输入样例:

13 13 3 3
#############
#GG.GGG#GGG.#
###.#G#G#G#G#
#.......#..G#
#G#.###.#G#G#
#GG.GGG.#.GG#
#G#.#G#.#.#.#
##G...G.....#
#G#.#G###.#G#
#...G#GGG.GG#
#G#.#G#G#.#G#
#GG.GGG#G.GG#
#############

输出样例:

炸弹放置在(8,12),消灭敌人最多为10

  • 深搜代码:

#include<cstdio>
#include<iostream>
#define INF 10000000
using namespace std;
char a[20][20];
int b[20][20];
int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};//四个方向
int maxx=0,mx,my,tx,ty,n,m;
int getsum(int x,int y)//计算一共可以消灭的敌人
{
    int sum=0;
    int i=x,j=y;
    while(a[i][j]!='#')//向下
    {
        if(a[i][j]=='G')sum++;
        i++;
    }
    i=x;j=y;
    while(a[i][j]!='#')//向上
    {
        if(a[i][j]=='G')sum++;
        i--;
    }
    i=x;j=y;
    while(a[i][j]!='#')//向左
    {
        if(a[i][j]=='G')sum++;
        j--;
    }
    i=x;j=y;
    while(a[i][j]!='#')//向右
    {
        if(a[i][j]=='G')sum++;
        j++;
    }
    return sum;
}

void dfs(int x,int y)
{
    int sum=getsum(x,y);
    if(sum>maxx)//更新最大值
    {
        maxx=sum;
        mx=x;
        my=y;
    }
    for(int i=0;i<4;i++)
    {
        tx=x+next[i][0];
        ty=y+next[i][1];
        if(tx>n||ty>m||tx<1||ty<1)//判断越界
            continue;
        if(b[tx][ty]==0&&a[tx][ty]=='.')//未被标记并且是空地
        {
            b[tx][ty]=1;//此处不用还原标记数组,因为不是找路径而是记录每个点消灭敌人的数
            dfs(tx,ty);
        }
    }
    return ;
}

int main()
{
    int sx,sy;
    scanf("%d%d%d%d",&n,&m,&sx,&sy);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            scanf(" %c",&a[i][j]);
    dfs(sx,sy);
    printf("炸弹放置在(%d,%d),消灭敌人最多为%d
",mx,my,maxx);
    return 0;
}
  • 广搜代码:

#include<cstdio>
#include<iostream>
#define INF 10000000
using namespace std;
char a[20][20];
int b[20][20];
int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};//四个方向

struct node//用结构体模拟队列
{
    int x;
    int y;

}que[410];

int getsum(int x,int y)//计算一共可以消灭的敌人
{
    int sum=0;
    int i=x,j=y;
    while(a[i][j]!='#')//向下
    {
        if(a[i][j]=='G')sum++;
        i++;
    }
    i=x;j=y;
    while(a[i][j]!='#')//向上
    {
        if(a[i][j]=='G')sum++;
        i--;
    }
    i=x;j=y;
    while(a[i][j]!='#')//向左
    {
        if(a[i][j]=='G')sum++;
        j--;
    }
    i=x;j=y;
    while(a[i][j]!='#')//向右
    {
        if(a[i][j]=='G')sum++;
        j++;
    }
    return sum;
}

int main()
{
    int n,m,sx,sy,tx,ty,mx,my;
    scanf("%d%d%d%d",&n,&m,&sx,&sy);
    //getchar();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            scanf(" %c",&a[i][j]);
    //初始化队列
    int head=1;
    int tail=1;
    //将起点入队
    que[tail].x=sx;
    que[tail].y=sy;
    tail++;//队尾指针++,队尾指针要指向空队列
    b[sx][sy]=1;//标记起点
    int maxx=getsum(sx,sy);
    int flag=0,sum;
    //开始广搜
    while(head<tail)//队列不为空
    {
        for(int i=0;i<4;i++)//四个方向搜索
        {
            //计算从父亲(head)点到下一个点
            tx=que[head].x+next[i][0];
            ty=que[head].y+next[i][1];
            if(tx<1||ty<1||tx>n||ty>m)//是否越界
            {
                continue;
            }
            if(b[tx][ty]==0&&a[tx][ty]=='.')//这个点没有走过并且是空地
            {
                b[tx][ty]=1;//标记走过,此处与深搜不同,不能还原标记
                //将此点入队
                que[tail].x=tx;
                que[tail].y=ty;
                tail++;//队尾指针++
                sum=getsum(tx,ty);
                if(sum>maxx)
                {
                    maxx=sum;
                    mx=tx;
                    my=ty;
                }
            }
        }
        head++;//四个方向可以进入路径的都已入队,将head出队
    }
    printf("炸弹放置在(%d,%d),消灭敌人最多为%d
",mx,my,maxx);
    return 0;
}
原文地址:https://www.cnblogs.com/boboyuzz/p/10426194.html