NTHU OJ 1015 - May the Right Force with you-圖論


Problem Link:http://acm.cs.nthu.edu.tw/problem/1015/


Description

In a sensational scene in the 8-th installment of the Voldemort book series, the robot Weighd was attacked and its rotating top and wings were severely damaged. Weighd cannot rotate its famous top and can only fly forward or make a right-turn. However, the brave Weighd must still navigate a magically created series of mazes to deliver its precious message to Ttoper.

Weighd enters each maze at the top-left square of the maze, takes one unit of time to travel between adjacent squares in the magic maze (forward or right), and cannot stay in one square to rotate itself, and thus change direction, for fear of evil jinx. Your task is to write a program to calculate the smallest number of squares that Weighd must travel to reach a certain square in each maze. Do not you worry about how? Weighd will feel its correct way through the force. Examples are:



Weighd can reach the location marked ``X" of the top maze in ``19" steps, but it cannot reach the marked location in the bottom maze at all.

Input

Input consists of multiple mazes. Each maze description starts with two integers, on a separate line, that represent its dimensions. The first integer N (1<=1000) represents the number of rows and the second M (1<=1000) represents the number of columns. The last maze is followed by a line containing two zeros that indicate the end of the input data and should not be processed as a valid situation.

The second line contains two integers, C (1<=N) and R (1<=M), that represent the column number and the row number of the square where Weighd must reach in the maze. Consecutive integers are separated by a blank space.

Each of the following N lines contains a sequence of 0s and 1s. The sequence is M characters long. The sequence does not contains blank spaces. A value one (1) represents a wall in the maze (that is, a square into which Weighd cannot fly).

Output

Output consists of one line for each maze. It will be in one of the following two formats:

1. an integer that represents the number of steps to be taken, inside the maze, by Weighd to reach its destination.
2. The string ``NOOO!", if no path can be found.

Sample Input

6 13
13 4
0000001111000
0111101111000
0000000000000
0000001111110
0000001111110
0000000000000
6 13
13 4
0000001111000
1111101111000
0000000000000
0001101111110
0001101111110
0001100000000
0 0

EOF

Sample Output

19
NOOO!

EOF

Code

#include <iostream>

using namespace std;

struct node
{
	int tag;
	int sorc_direction;
	int up : 1;
	int down : 1;
	int left : 1;
	int right : 1;
};//define up=1,down=2,left=3,right=4
void sol();
void div_sol(int i, int j);
void up(int i, int j);
void down(int i, int j);
void left(int i, int j);
void right(int i, int j);
int count1, count2 = 0;
int N, M;
int R, C;
node maze[1001][1001];
int main()
{
	cin >> N >> M;
	char tag;
	while (N&&M)
	{
		count1 = 1000 * 1000*1000;
		count2=0;
		cin >> C >> R;
		int i, j;
		for (i = 1; i <= N; i++)
		{
			for (j = 1; j <= M; j++)
			{
				cin >> tag;
				maze[i][j].tag = tag - '0';
				maze[i][j].up = maze[i][j].down = maze[i][j].left = maze[i][j].right = 0;
			}
		}
		sol();
		if (count1 == 1000 * 1000*1000)
			cout << "NOOO!" << endl;
		else
			cout << count1-1 << endl;
		cin >> N >> M;
	}
	return 0;
}
void sol()
{
	if (!maze[1][1].tag)
	{
		count2=1;
		maze[1][1].sorc_direction = 2;
		div_sol(1, 1);
		for (int i = 1; i <= N; i++)
		{
			for (int j = 1; j <= M; j++)
				maze[i][j].up = maze[i][j].down = maze[i][j].left = maze[i][j].right = 0;
		}
		count2 = 1;
		maze[1][1].sorc_direction = 4;
		div_sol(1, 1);
	}
}
void div_sol(int i, int j)
{
	if (i == R&&j == C)
	{
		if (count2<count1)
		{
			count1 = count2;
			return;
		}
	}
	else
	{
		switch (maze[i][j].sorc_direction)
		{
		case 1: right(i, j); up(i, j); break;
		case 2: left(i, j); down(i, j); break;
		case 3:up(i, j); left(i, j);  break;
		case 4: down(i, j); right(i, j); break;
		}
	}
	return;
}
void up(int i, int j)
{
	if (!maze[i][j].up&&i>1 && !maze[i - 1][j].tag)
	{
		count2++;
		maze[i][j].up = 1;
		maze[i - 1][j].sorc_direction = 1;
		div_sol(i - 1, j);
		count2--;
	}
}
void down(int i, int j)
{
	if (!maze[i][j].down&&i<N&&!maze[i + 1][j].tag)
	{
		count2++;
		maze[i][j].down = 1;
		maze[i + 1][j].sorc_direction = 2;
		div_sol(i + 1, j);
		count2--;
	}
}
void left(int i, int j)
{
	if (!maze[i][j].left&&j>1 && !maze[i][j - 1].tag)
	{
		count2++;
		maze[i][j].left = 1;
		maze[i][j - 1].sorc_direction = 3;
		div_sol(i, j - 1);
		count2--;
	}
}
void right(int i, int j)
{
	if (!maze[i][j].right&&j < M&&!maze[i][j + 1].tag)
	{
		count2++;
		maze[i][j].right = 1;
		maze[i][j + 1].sorc_direction = 4;
		div_sol(i, j + 1);
		count2--;
	}
}



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