炸弹游戏规则:在一个n*n的方阵里,每一个方格分别代表空地,敌人,墙,三种元素的分布为随机分布,现在玩家要从地图的某一个空地(已知坐标点)出发,走到一个空地上放置炸弹,炸弹可以炸毁该点对应行列上的所有敌人,但是炸弹不能炸穿墙,要求的是玩家在哪一个点放置炸弹能够炸掉最多敌人,最多炸几个?(注意:必须考虑玩家从出发点到放置炸弹点之间的可通过路径,即玩家只能通过空地走到放置炸弹点,且不能走墙外。)
/*在程序中,我们自定义一个规格不超过20*20的地图,用“#”表示墙,“ . ” 表示空地,“G”表示敌人*/
#include<stdio.h>
struct note //定义一个结构体来产生一个队列
{
int x;
int y;
};
char a[20][20]; //假设地图的规格不超过20*20;
int getnum(int i,int j) //统计在(i,j)炸掉的敌人个数的函数;
{
int sum,x,y;
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; //重新定位回(i,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,所以队列的扩展不会超过400个,加上队尾,所以为401个;
int head,tail; //定义队列的队头和队尾;
int book[20][20]={0}; //book用来标记哪些点是已经走过的,防止重复走,标记为1时表示为走过,初始化时全为0;
int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}}; //next数组分别表示向右,向下,向左,向上走一步;
int m,n,i,j,startx,starty,max=0,sum=0,mx,my,k,tx,ty; //m,n分别为地图的规格,i,j为定义地图时for循环用到的变量,(startx,starty)为玩家起始点,max为消灭的最多敌人,sum为在每一个空地所能消灭的敌人的个数,(mx,my)为放置炸弹的坐标,k为分别进行向上下左右进行移动的标记次数,(tx,ty)为进行移动后玩家的新坐标;
scanf("%d%d%d%d",&m,&n,&startx,&starty); //自定义地图;
for(i=0;i<=m-1;i++)
scanf("%s",a[i]);
while(a[startx][starty]=='#'||a[startx][starty]=='G') //判断玩家的起点是否为空地,如果不是就重新输入;
{
printf("炸弹必须放置在空地,请重新输入(startx,starty):");
scanf("%d%d",&startx,&starty);
}
head=1; //初始化队列;
tail=1;
que[tail].x=startx;
que[tail].y=starty;
book[startx][starty]=1; //对玩家起点进行标记,表示已经走过;
tail++; //队尾扩展;
max=getnum(startx,starty); 统计起点所能消灭的敌人,调用getnum函数;
mx=startx;
my=starty;
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>m-1||ty<0||ty>n-1) //判断玩家有没有走到地图外
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); //计算该点消灭敌人的个数;
if(max<sum); //如果该点消灭的敌人个数比之前的点的个数多,就把max更新为现在的点的个数;
{
max=sum;
mx=tx;
my=ty;
}
}
}
head++; //队列扩展的是根据已入队的点相邻的点,当一个点的相邻点都扩展入队列后,则将这个点出队,这样才能保证后面的点也能入队;
}
printf("将炸弹放在x=%d,y=%d处,可以消灭%d个敌人\n",mx,my,max);
getchar();getchar();
return 0;
}