啊哈算法---宝岛探险(广度优先搜索)
#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; }