再解炸弹人(深度优先和广度优先)

现在炸弹不是想放在那里就能放在那里的了,必须由小人能够走到的地方才能放置炸弹。比如下面这个例子小人默认站在(3,3)这个位置。请问放在何处最多可以消灭多个敌人。

解释:上面解炸弹人的方法有可能小人并不能走到那里去,也就不能放置炸弹。我们可以通过深度优先和广度优先来进行搜索,确保该点小人可以到达,再在可到达的点周围确定可以消灭敌人的数目。

dfs:先更新最大值,再循环

#include <stdio.h>
int book[51][51] = {0};
char a[51][51];//记录地图
int max,n,m,mx,my;
int getsum(int i,int j)
{
    int sum,x,y;
    sum = 0;
    x = i;
    y = j;
    while(a[x][y]!='#')//不为墙  向上检查 
    {
        if(a[x][y]=='G')
        {
            sum++;
        }
        x--;
    }
    x = i;
    y = j;
    while(a[x][y]!='#')//不为墙  向下检查 
    {
        if(a[x][y]=='G')
        {
            sum++;
        }
        x++;
    }                        
    x = i;
    y = j;
    while(a[x][y]!='#')//不为墙  向左检查 
    {
        if(a[x][y]=='G')
        {
            sum++;
        }
        y--;
    }
                
    x = i;
    y = j;
    while(a[x][y]!='#')//不为墙  向右检查 
    {
        if(a[x][y]=='G')
        {
            sum++;
        }
        y++;
    }
    return sum;            
 } 
 
void dfs(int x,int y)
{
    int tx,ty,k,sum;
    int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};//搜索的方向,右,下,左,上 
    sum = getsum(x,y);//以该点为中心,向四个方向寻找可以消灭敌人的总数 
    if(sum>max)//更新最大值并且记录横纵坐标 
    {
        max = sum;
        mx = x;
        my = y;
    }
    for(k = 0;k <= 3;k++)
    {
        tx = x+next[k][0];
        ty = y+next[k][1];
        if(tx<0||tx>n-1||ty<0||ty>m-1)//边界 
        {
            continue;
        }
        if(a[tx][ty]=='.'&&book[tx][ty]==0)//判断是否为平地或曾经走过 
        {
            book[tx][ty] = 1;
            dfs(tx,ty);
        }
    }
    return;
    

}
int main()
{
    int i,x,y;
    scanf("%d%d%d%d",&n,&m,&x,&y);//读入行和列,起始坐标
    for(i = 0;i < n;i++)//读入地图 
    {
        scanf("%s",a[i]);
    }
    book[x][y]=1;
    max = getsum(x,y);
    mx = x;
    my = y;
    dfs(x,y);
    printf("%d",max);
    return 0;
}

bfs:先循环,再更新最大值

#include <stdio.h>
struct node
{
    int x;//横坐标 
    int y;//纵坐标 
};
char a[51][51];//记录地图
int getsum(int i,int j)
{
    int sum,x,y;
    sum = 0;
    x = i;
    y = j;
    while(a[x][y]!='#')//不为墙  向上检查 
    {
        if(a[x][y]=='G')
        {
            sum++;
        }
        x--;
    }
    x = i;
    y = j;
    while(a[x][y]!='#')//不为墙  向下检查 
    {
        if(a[x][y]=='G')
        {
            sum++;
        }
        x++;
    }                        
    x = i;
    y = j;
    while(a[x][y]!='#')//不为墙  向左检查 
    {
        if(a[x][y]=='G')
        {
            sum++;
        }
        y--;
    }
                
    x = i;
    y = j;
    while(a[x][y]!='#')//不为墙  向右检查 
    {
        if(a[x][y]=='G')
        {
            sum++;
        }
        y++;
    }
    return sum;            
 } 
int main()
{
    struct node que[2501];
    int book[51][51] = {0};//定义一个标记数组并全部初始化为0 
    int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};//搜索的方向,右,下,左,上 
    int i,j,sum,k,mx,my,x,y,n,m,head,tail,max = 0,tx,ty;
    head = 1;
    tail = 1; 
    scanf("%d%d%d%d",&n,&m,&x,&y);//读入行和列,起始坐标
    for(i = 0;i < n;i++)//读入地图 
    {
        scanf("%s",a[i]);
    }
    que[tail].x = x;//初始化 
    que[tail].y = y;
    book[x][y] = 1; 
    tail++;
    
    max = getsum(x,y);//记录初始点的信息 
    mx = x;
    my = y;
    
    while(head<tail)
    {
        for(k = 0;k <= 3;k++)
        {
            tx = que[head].x+next[k][0];
            ty = que[head].y+next[k][1];
            if(tx<0||tx>n-1||ty<0||ty>m-1)//边界 
            {
                continue;
            }
            if(a[tx][ty]=='.'&&book[tx][ty]==0)//判断是否为平地或曾经走过 
            {
                book[tx][ty] = 1;
                que[tail].x = tx;
                que[tail].y = ty;
                tail++;
                sum = getsum(tx,ty);//以该点为中心,向四个方向寻找可以消灭敌人的总数 
                if(sum>max)//更新最大值并且记录横纵坐标 
                {
                    max = sum;
                    mx = tx;
                    my = ty;
                }
            }
        }
        head++; 
    } 
//    printf("将炸弹放置在(%d,%d)处,最大可消灭敌人数为:%d\n",mx,my,max); 
    printf("%d",max);
    return 0; 
 } 

猜你喜欢

转载自blog.csdn.net/qq_40761693/article/details/86775601
今日推荐