第一題:
解題大致過程:
- 首先要提前準備的四個數組
1.1 第一個是用來存放地圖的
1.2 第二個用來存放保存記錄,
1.3 第三個用來進行隊列的
1.4 第四個是存放上下左右方向的 - 就一個隊列循環結束即可,不需要像深搜一樣
- 在while 隊列中
3.1 隊列過程中每到一個位置時會進行上下左右進行列舉,這裏用一個for循環,
3.2 在循環中開始獲取下一個位置,獲取到之後首先判斷是否當前位置是超過這張地圖的範圍,是的話 continue 直接換位置
3.3 判斷這個點是否爲障礙物,或者是否曾經訪問過這個點,不是的話增加到隊列中尾部加一
3.4 判斷這個點是否是終點,是的話用一個flag=1來表示已經找到了,直接退出for循環列舉方向
3.5 結束for在while中判斷是否得到flag爲1的信號及時退出,沒有的話說明這個點已經所有位置都訪問過,進行隊列中下一個位置
輸入條件:
5 4
0 0 1 0
0 0 0 0
0 0 1 0
0 1 0 0
0 0 0 1
1 1 4 3
代碼:
#include <stdio.h>
struct node{
int x; //橫座標
int y; //縱座標
int f; //父親在隊列中的編號
int s; //步數
};
int main()
{
struct node que[2501]; //因爲地圖不會超過50*50的,也因此隊列擴展不會超過2500個
int a[51][51]={0},book[51][51]={0};
int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int head,tail,n,m,i,j,startx,starty,p,q,flag,tx,ty,k;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
scanf("%d",&a[i][j]);
scanf("%d%d%d%d",&startx,&starty,&p,&q);
//進行隊列初始化
head = 1;
tail = 1;
//往隊列中插入迷宮入口座標
que[tail].x = startx;
que[tail].y = starty;
que[tail].f = 0;
que[tail].s = 0;
tail++;
book[startx][starty]=1;
flag = 0; // 用來標記是否達到目標點,0表示暫時還沒有到達
//當隊列不爲空的時候循環
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<1||tx>n||ty<1||ty>m){
continue;
}
//判斷是否是障礙物或者已經在路徑中
if(a[tx][ty]==0&&book[tx][ty]==0)
{
//把這個點標記爲已經走過
//注意寬搜每個點只入隊一次,所以和深搜不同,不需要將book還原
book[tx][ty]=1;
//插入新的點到隊列中
que[tail].x = tx;
que[tail].y = ty;
que[tail].f = head;
que[tail].s = que[head].s+1;
tail++;
}
//判斷到目標點了,停止擴展,任務結束,退出循環
if(tx==p&&ty==q)
{
flag=1;
break;
}
}
if(flag==1)
break;
head++; //第一個擴展點結束後才進行增1
}
//指向末尾最後一個的點數
printf("%d",que[tail-1].s);
return 0;
}
運行結果爲:7
————————————————————————————————————————
第二題 找到合理的位置求出能夠消滅最多的敵人
必須在空曠的位置走
輸入條件:
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#
#############
代碼:
#include <stdio.h>
struct node{
int x; //橫座標
int y; //縱座標
};
char a[20][21]; //定義地圖
//得到對應的點能炸敵人的和
int getnum(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[401];
int head,tail; //定義頭尾
int book[20][20]={0};
int next[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
int i,j,n,m,startx,starty,mx,my,tx,ty,sum=0,max;
scanf("%d%d%d%d",&n,&m,&startx,&starty); //輸入行列
for(i=0;i<n;i++)
scanf("%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)
{
//枚舉四個方向
for(i=0;i<4;i++)
{
//嘗試走的下一個點座標
tx=que[head].x+next[i][0];
ty=que[head].y+next[i][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 = getnum(tx,ty);
if(sum>max){
max = sum;
mx = tx; //記錄點
my = ty;
}//if
}//if
}//for
head++; //進行擴展
}//while
printf("炸彈放在(%d,%d)中消滅最多敵人數:%d",mx,my,max);
return 0;
}
輸出結果爲:炸彈放在(7,11)中消滅最多敵人數:10
可以加羣一起討論891507813