1. 程式人生 > 實用技巧 >spring security 核心切面

spring security 核心切面

題目如下:

在H * W的地圖上有N個乳酪工廠,每個工廠分別生產硬度為1-N的乳酪。有一隻老鼠準備從出發點吃遍每一個工廠的乳酪。老鼠有一個體力值,初始時為1,每吃一個工廠的乳酪體力值增加1(每個工廠只能吃一次),且老鼠只能吃硬度不大於當前體力值的乳酪。 老鼠從當前格到上下左右相鄰的無障礙物的格需要時間1單位,有障礙物的格不能走。走到工廠上時即可吃到該工廠的乳酪,吃乳酪時間不計。問吃遍所有乳酪最少用時


輸入為:

第一行三個整數H(1 <= H <= 1000)、W(1 <= W <=1000)、N(1 <= N <= 9),之後H行W列為地圖, “.“為空地, ”X“為障礙物,”S“為老鼠洞,N表示有N個生產乳酪的工廠,硬度為1-N。


輸出為:

輸出一個整數,代表老鼠吃遍所有乳酪的最少時間花費。


輸入樣例1

3 3 1

S..

...

..1


輸出樣例1

4


輸入樣例2

4 5 2

.X..1

....X

.XX.S

.2.X.


輸出樣例2

12


輸入樣例3

10 10 9

.X...X.S.X

6..5X..X1X

...XXXX..X

X..9X...X.

8.X2X..X3X

...XX.X4..

XX....7X..

X..X..XX..

X...X.XX..

..X.......


輸出樣例3

91


解題思路:

首先,這道題是一道非常好的bfs題目。由於這道題只能去吃比自己體力值小的乳酪,且吃完一個乳酪後,自身體力值加1。看似很難,實際上我們可以按照順序去吃乳酪即可。例如:從起點開始到第一個乳酪進行一次bfs,獲取到從起點到第一個乳酪的最短用時。清空完狀態陣列後(請讀者思考為什麼要清空?),以乳酪1為起點到第二個乳酪進行一次bfs,獲取到從第一個乳酪到第二個乳酪的最短用時。一直到最後一個乳酪。以此類推,將這些乳酪的最短用時相加,即為從起點到指定乳酪的最少用時。


這道題的注意點:

1.起點也是可以進行移動的(不算障礙物)(本人在這裡debug了很久)

2.在查詢指定的乳酪時,可以跨越比自己體力值大的乳酪。例如:你要從3乳酪找到4乳酪,但是5乳酪在4乳酪的前面,這時也是可以跨越5乳酪去找4乳酪的。(總之就是一句話,乳酪不算障礙物!)

在每個測試例項結束時,清空儲存最短用時的變數。

在設定圖中的寬高時,儘管圖中說了小於等於1000,但是我們還要將寬高設定的大一點,以免意外情況發生!(有些題目測試例項可能會有類似於空字串等等)


程式碼如下:

#include <iostream>
#include <cstdio>
#include <queue>
#include <map>
#define INF 0x3f3f3f3f
using namespace std;
int h, w, n;
long Time = 0;                              //代表走的最少時間(初始狀態為0)
map <pair<int, int>, char > relation;   //將每個頂點和它們的座標關聯起來
map <int, char> cheese;                 //將圖中的乳酪跟數字關聯起來
queue<pair<int, int> > Q;                //代表儲存每個頂點座標的Q
char Graph[1002][1002];                  //代表地圖
long status[1002][1002];                  //代表節點訪問狀態的陣列(初始都為INF)
void bfs(int x,int y,int n);             //代表進行廣度優先搜尋的函式

void bfs(int x, int y, int n)
{
	int i, j, k;
	int movex, movey;            //代表正在移動的頂點座標
	int endx, endy;              //代表終點座標
	endx = x;
	endy = y;
	pair<int, int > temp;       //代表正在遍歷的頂點
	for (i = 1; i <= n; i++)   //代表要查詢的乳酪的個數
	{
		Q.push(make_pair(endx, endy));       //將起點進行入隊
		for (j = 0; j < h; j++)
		{
			for (k = 0; k < w; k++)
			{
				status[j][k] = INF;        //每一次進行寬度優先遍歷時(乳酪的查詢時),我們都要清空一下狀態陣列,以便進行下一次乳酪的查詢
			}
		}
		status[endx][endy] = 0;              //起點距離起點的時間為0
		while (!Q.empty())
		{
			temp = Q.front();
			Q.pop();   
			for (j = -1; j <= 1; j++)
			{
				for (k = -1; k <= 1; k++)
				{
					if (j == 0 || k == 0)
					{
						movex = temp.first + j;
						movey = temp.second + k;
						if (movex >= 0 && movex < h && movey >= 0 && movey < w && Graph[movex][movey] != 'X' && status[movex][movey] == INF)
						{
							if (Graph[movex][movey] == cheese[i])
							{
								status[movex][movey] = status[temp.first][temp.second] + 1;
								Time += status[movex][movey];
								endx = movex;
								endy = movey;
							}
							else if (Graph[movex][movey] == '.' || (Graph[movex][movey] >= '1' && Graph[movex][movey] <='9' || Graph[movex][movey] == 'S'))
							{
								Q.push(make_pair(movex, movey));
								status[movex][movey] = status[temp.first][temp.second] + 1;
							}
						}
					}
				}
			}
		}
	}
}

int main()
{
	int i, j,k=1;
	char x;
	while (scanf("%d %d %d", &h, &w, &n) != EOF)
	{
		for (i = 0; i < h; i++)
		{
			for (j = 0; j < w; j++)
			{
				cin >> x;
				Graph[i][j] = x;
				relation[make_pair(i, j)] = x; 
			}
		}
		for (x = '1';x <= '9'; x++)
		{
			cheese[k] = x;   
			k++;
		}
		for (i = 0; i < h; i++)
		{
			for (j = 0; j < w; j++)
			{
				if (Graph[i][j] == 'S')
				{
					bfs(i, j,n);      //代表老鼠在起點出發進行廣度優先搜尋
				}
			}
		}
		printf("%ld\n", Time);
		Time = 0;
		k = 1;
	}
}