天天看點

NYOJ 58 最小步數(BFS && DFS)

最少步數

時間限制: 3000 ms  |  記憶體限制: 65535 KB 難度: 4

描述

這有一個迷宮,有0~8行和0~8列:

 1,1,1,1,1,1,1,1,1

 1,0,0,1,0,0,1,0,1

 1,0,0,1,1,0,0,0,1

 1,0,1,0,1,1,0,1,1

 1,0,0,0,0,1,0,0,1

 1,1,0,1,0,1,0,0,1

 1,1,0,1,0,1,0,0,1

 1,1,0,1,0,0,0,0,1

 1,1,1,1,1,1,1,1,1

0表示道路,1表示牆。

現在輸入一個道路的坐标作為起點,再如輸入一個道路的坐标作為終點,問最少走幾步才能從起點到達終點?

(注:一步是指從一坐标點走到其上下左右相鄰坐标點,如:從(3,1)到(4,1)。)

輸入

第一行輸入一個整數n(0<n<=100),表示有n組測試資料;

随後n行,每行有四個整數a,b,c,d(0<=a,b,c,d<=8)分别表示起點的行、列,終點的行、列。

輸出
輸出最少走幾步。
樣例輸入
2
3 1  5 7
3 1  6 7      
樣例輸出
12
11
      
代碼:
#include<stdio.h>
#include<string.h>
#define INF 0x3f3f3f;
int x,y,ex,ey,min;
int dx[4]={1,-1,0,0};
int dy[4]={0,0,-1,1};
int map[9][9]={
 1,1,1,1,1,1,1,1,1,
 1,0,0,1,0,0,1,0,1,
 1,0,0,1,1,0,0,0,1,
 1,0,1,0,1,1,0,1,1,
 1,0,0,0,0,1,0,0,1,
 1,1,0,1,0,1,0,0,1,
 1,1,0,1,0,1,0,0,1,
 1,1,0,1,0,0,0,0,1,
 1,1,1,1,1,1,1,1,1,
 };
int dfs(int x,int y,int c)
{
 	if(x==ex&&y==ey)
 	{
 		if(c<min)
 		{
 			min=c;
		}
	}
	else
	{
		for(int i=0;i<4;i++)
		{
			int nx=x+dx[i];
			int ny=y+dy[i];
			if(map[nx][ny]==0&&c+1<min)
			{
				map[nx][ny]=1;
			    dfs(nx,ny,c+1);
			    map[nx][ny]=0;
			}
		}
	}
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int c=0;
		scanf("%d%d%d%d",&x,&y,&ex,&ey);
		min=INF;
		map[x][y]=1;
		dfs(x,y,c);
		map[x][y]=0;
		printf("%d\n",min);
	}
	return 0;
}
           
</pre></dd><dd style="margin:0px; padding:0px"><pre code_snippet_id="1792451" snippet_file_name="blog_20160729_3_5224033" name="code" class="cpp">BFS
           
#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
int x,y,ex,ey;
int map[9][9]={
 1,1,1,1,1,1,1,1,1,
 1,0,0,1,0,0,1,0,1,
 1,0,0,1,1,0,0,0,1,
 1,0,1,0,1,1,0,1,1,
 1,0,0,0,0,1,0,0,1,
 1,1,0,1,0,1,0,0,1,
 1,1,0,1,0,1,0,0,1,
 1,1,0,1,0,0,0,0,1,
 1,1,1,1,1,1,1,1,1,
};
int dx[4]={0,0,-1,1};
int dy[4]={1,-1,0,0};
bool vis[9][9];//标記數組,不可用map[x][y]=1,來标記,會出錯; 
struct node
{
	int x,y,step;
};
int bfs()
{
	node s;
	s.x=x,s.y=y,s.step=0;
	vis[x][y]=true;
	queue<node>q;
	q.push(s);
	while(!q.empty())
	{
		node now=q.front();
		q.pop();
		if(now.x==ex&&now.y==ey)
		{
			return now.step;//入隊列有先後順序,先找到終點的就是最小的步數,可直接輸出step;
		}
		for(int i=0;i<4;i++)
		{
			node end;
			end.x=now.x+dx[i];
			end.y=now.y+dy[i];
			end.step=now.step;//保證每次走與中心點相關的點前步數相同;
			if(map[end.x][end.y]==0&&!vis[end.x][end.y])
			{
				vis[end.x][end.y]=true;
				end.step+=1;//能走則加一步,并标記  入隊列;
				q.push(end);
			}
		}
	}
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		memset(vis,false,sizeof(vis));//每次更新; 
		scanf("%d%d%d%d",&x,&y,&ex,&ey);
		int ans=bfs();
		printf("%d\n",ans);
	}
	return 0;
}