隊列 廣搜 nyoj 58 最少步數

最少步數

時間限制: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
來源
[苗棟棟]原創
上傳者

苗棟棟


一AC,果然痛快!好久沒有這種感覺了!

代碼如下:

#include<stdio.h>
#include<string.h>
#include<queue>
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
typedef struct{
	int x,y;
	int step;
}node;
node begin,end;

int visit[1000100];
int b[2][4]={0,1,0,-1,1,0,-1,0};//前進的橫縱座標變化
int hash(node u)
{
	return u.x*100+u.y;//標記 該節點
}
int find(node u,node v)
{
	return u.x==v.x&&u.y==v.y;
}
int main()
{
	int i,j;
	int t;
	scanf("%d",&t);
	while(t--)
	{
		mem(visit);
		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
		};
		scanf("%d%d",&begin.x,&begin.y);
		begin.step=0;
		scanf("%d%d",&end.x,&end.y);
		queue<node>q;
		q.push(begin);
		visit[hash(begin)]=1;
		map[begin.x][begin.y]=1;
		while(!q.empty())
		{
			node u=q.front();
			q.pop();
			if(find(u,end))
			{
				printf("%d\n",u.step);
				break;
			}
			for(int i=0;i<4;++i)
			{
				if(map[u.x+b[0][i]][u.y+b[1][i]]==0)
				{
					map[u.x+b[0][i]][u.y+b[1][i]]=1;
					node v=u;
					v.x+=b[0][i];
					v.y+=b[1][i];
					v.step++;
					if(!visit[hash(v)])
					{
						visit[hash(v)]=1;
						q.push(v);
					}
				}	
			}
		}
		while(!q.empty())
		q.pop();
	}
	return 0;
} 



發佈了305 篇原創文章 · 獲贊 11 · 訪問量 26萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章