1. 程式人生 > >#113-【廣搜】青銅蓮花池

#113-【廣搜】青銅蓮花池

題目描述

為了讓奶牛們娛樂和鍛鍊,農夫約翰建造了一個美麗的池塘。這個長方形的池子被分成了M行N列個方格(1 ≤ M, N ≤30)。一些格子是堅固得令人驚訝的蓮花,還有一些格子是岩石,其餘的只是美麗、純淨、湛藍的水。

貝西正在練習芭蕾舞,她站在一朵蓮花上,想跳到另一朵蓮花上去,她只能從一朵蓮花跳到另一朵蓮花上,既不能跳到水裡,也不能跳到岩石上。

貝西的舞步很像象棋中的馬步:每次總是先橫向移動M1 (1 ≤ M1 ≤ 30)格,再縱向移動M2 (1 ≤ M2 ≤ 30, M1     M2)格,或先縱向移動M1格,再橫向移動M2格。最多時,貝西會有八個移動方向可供選擇。

給定池塘的佈局和貝西的跳躍長度,請計算貝西從起點出發,到達目的地的最小步數,我們保證輸入資料中的目的地一定是可達的。

輸入

第一行:四個用空格分開的整數:M,N,M1和M2

第二行到M + 1行:第i + 1行有N個用空格分開的整數,描述了池塘第i行的狀態:0 為水,1 為蓮花,2 為岩石,3 為貝西所在的起點,4 為貝西想去的終點。

輸出

第一行:從起點到終點的最少步數

樣例輸入

4 5 1 2 
1 0 1 0 1 
3 0 2 0 4 
0 1 2 0 0 
0 0 0 1 0 

樣例輸出

2

提示

樣例解釋:貝西從第二行的最左邊出發,目標是第二行的最右邊。貝西先跳到第一行第三列的蓮花上,再跳到終點,需要兩步。

來源

廣搜 

基本BFS,不用多說。

#include <iostream>
#include <queue>

#define SIZE 110

using namespace std;

struct node
{
	int x, y, dis;
};

queue<node> q;
int a[SIZE][SIZE], dx[8], dy[8];

int main(void)
{
	int n, m, i, j, x, y, r, c, sx, sy;
	
	scanf("%d%d%d%d", &n, &m, &x, &y);
	for (i = 1; i <= n; ++i) // 輸入
	{
		for (j = 1; j <= m; ++j)
		{
			scanf("%d", &a[i][j]);
			if (a[i][j] == 3)
			{
				sx = i;
				sy = j;
			}
		}
	}
	
	dx[0] = -y; // 前進方向
	dy[0] = -x;
	dx[1] = x;
	dy[1] = y;
	dx[2] = x;
	dy[2] = -y;
	dx[3] = -x;
	dy[3] = y;
	dx[4] = -x;
	dy[4] = -y;
	dx[5] = y;
	dy[5] = x;
	dx[6] = y;
	dy[6] = -x;
	dx[7] = -y;
	dy[7] = x;
	q.push({sx, sy, 0});
	while (!q.empty()) // BFS模板
	{
		x = q.front().x;
		y = q.front().y;
		for (i = 0; i < 8; ++i)
		{
			r = x + dx[i];
			c = y + dy[i];
			if (a[r][c] == 4)
			{
				printf("%d", q.front().dis + 1); // 到達終點,輸出步數
				return 0;
			}
			if (a[r][c] == 1)
			{
				a[r][c] = 0;
				q.push({r, c, q.front().dis + 1});
			}
		}
		q.pop();
	}
	
	return 0;
}