啊哈算法---宝岛探险(广度优先搜索)

#include<stdio.h>
struct note
{
    int x;//横坐标
    int y;//纵坐标
};
char a[20][21];//用来存储地图
int getnum(int i, int j)
{
    int sum, x, y;
    sum = 0;//sum用来计数(可以消灭的敌人数),需要初始化为0
    //将坐标i,j复制到两个新变量x,y中,为了方便向上下左右四个方向统计可以消灭的敌人数
    //向上统计
    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 note que[401];//因为地图大小不超过20*20,因此队列扩展不会超过401
    int head, tail;
    int book[20][20] = { 0 };//定义一个标记数组并全部初始化为0
    int i, j, k, sum, max = 0, mx, my, n, m, startx, starty, tx, ty;

    //定义一个方向数组,默认的方向顺序为顺时针,右、下、左、上
    int next[4][2] = { { 0, 1 },//向右走
    { 1, 0 },//向下走
    { 0, -1 },//向左走
    { -1, 0 } };//向上走
    
    //读入n和m,n表示有多少行字符,m表示每行有多少列
    scanf_s("%d %d %d %d", &n, &m,&startx,&starty);//输入地图大小

    //读入n行字符
    for (i = 0; i <= n-1 ; i++)
            scanf_s("%s", a[i]);//输入地图

    //队列初始化
    head = 1;
    tail = 1;

    //往队列插入小人起始坐标
    que[tail].x = startx;
    que[tail].y = starty;
    tail++;
    book[startx][starty] = 1;
    max = getnum(startx, starty);
    mx = startx;
    my = starty;

    //当队列不为空的时候循环
    while (head < tail)
    {
        //枚举4个方向
        for (k = 0; k <= 3; k++)
        {
            //计算下一个点的坐标
            tx = que[head].x + next[k][0];
            ty = que[head].y + next[k][1];
            //判断是否越界
            if (tx<1 || tx>n || ty<1 || ty>m)
                continue;
            //判断该点是否为平地或者已经走过
            if (a[tx][ty] == '.' && book[tx][ty] == 0)
            {
                //每个点只入队一次,所以需要标记这个点已经走过
                book[tx][ty] = 1;//标记这个点已经走过
                //插入新扩展的点到队列中
                que[tail].x = tx;
                que[tail].y = ty;
                tail++;


                //统计当前点可以消灭的敌人总数
                sum = getnum(tx, ty);
                //更新max值
                if (sum > max)
                {
                    //如果当前统计出所能消灭敌人数大于max,则更新max
                    //并用mx和my记录该点坐标
                    max = sum;
                    mx = tx;
                    my = ty;
                }
            }
        }
        //注意这地方千万不要忘记,当一个点扩展结束后,
        //必须要head++才能对后面的点进行扩展
        head++;
    }
    //最后输出这个点和最多可以消灭的敌人总数
    printf("将炸弹放在(%d,%d)处,可以消灭%d个敌人\n", mx,my,max);

    getchar();
    getchar();
    return 0;

}

 

posted @ 2017-02-23 17:28  walanwalan  阅读(1011)  评论(0编辑  收藏  举报