Cheese Aizu-0558(BFS)

チーズ ()

問題

今年も JOI 町のチーズ工場がチーズの生産を始め,ねずみが巣から顔を出した.JOI 町は東西南北に區畫整理されていて,各區畫は巣,チーズ工場,障害物,空き地のいずれかである.ねずみは巣から出発して全てのチーズ工場を訪れチーズを 1 個ずつ食べる.

この町には,N 個のチーズ工場があり,どの工場も1種類のチーズだけを生産している.チーズの硬さは工場によって異なっており,硬さ 1 から N までのチーズを生産するチーズ工場がちょうど 1 つずつある.

ねずみの最初の體力は 1 であり,チーズを 1 個食べるごとに體力が 1 増える.ただし,ねずみは自分の體力よりも硬いチーズを食べることはできない.

ねずみは,東西南北に隣り合う區畫に 1 分で移動することができるが,障害物の區畫には入ることができない.チーズ工場をチーズを食べずに通り過ぎることもできる.すべてのチーズを食べ終えるまでにかかる最短時間を求めるプログラムを書け.ただし,ねずみがチーズを食べるのにかかる時間は無視できる.

入力

入力は H+1 行ある.1 行目には 3 つの整數 H,W,N (1 ≤ H ≤ 1000,1 ≤ W ≤ 1000,1 ≤ N ≤ 9) がこの順に空白で區切られて書かれている.2 行目から H+1 行目までの各行には,'S','1', '2', ..., '9','X','.' からなる W 文字の文字列が書かれており,各々が各區畫の狀態を表している.北から i 番目,西から j 番目の區畫を (i,j) と記述することにすると (1 ≤ i ≤ H, 1 ≤ j ≤ W),第 i+1 行目の j 番目の文字は,區畫 (i,j) が巣である場合は 'S' となり,障害物である場合は 'X' となり,空き地である場合は '.' となり,硬さ 1, 2, ..., 9 のチーズを生産する工場である場合はそれぞれ '1', '2', ..., '9' となる.入力には巣と硬さ 1, 2, ..., N のチーズを生産する工場がそれぞれ 1 つずつある.他のマスは障害物または空き地であることが保証されている.ねずみは全てのチーズを食べられることが保証されている.

出力

すべてのチーズを食べ終えるまでにかかる最短時間(分)を表す整數を 1 行で出力せよ.

入出力例

入力例 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

問題文と自動審判に使われるデータは、情報オリンピック日本委員會が作成し公開している問題文と採點用テストデータです。

 

咱也看不懂。。但也不敢問。。只能用翻譯了hhh


題意應該是從起點S開始
到1、2、3....n的最短距離(因爲他說老鼠不能喫比自己體力大的)
 輸入:第一行三個整數H(1 <= H <= 1000)、W(1 <= W <=1000)、N(1 <= N <= 9),之後H行W列爲地圖, “.“爲空地, ”X“爲障礙物,”S“爲老鼠洞, 1-N代表硬度爲1-N的奶酪的工廠。輸出最少用時。
*

//Cheese Aizu - 0558 
#include <iostream>
#include <queue>
#include <cstring>

using namespace std;

char MAP[1005][1005];//地圖
int vis[1005][1005]; 
int dir[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};//方向向量 
int h,w,n,head,sum=0;

struct Node{
	int x;
	int y;
	int step;
};

bool check(Node s){//約束條件檢驗 
	if(s.x>=0 && s.x<h && s.y>=0 && s.y<w && MAP[s.x][s.y]!='X' && !vis[s.x][s.y]){
		return 1;
	} else return 0;
}

//每次bfs的起點都不同,這次bfs的終點要被記錄爲下次bfs的起點
void bfs(Node &s){//引用傳遞 
	memset(vis,0,sizeof(vis));
	queue<Node> q;
	Node now,next;//定義兩個狀態,當前和下一個 
	s.step = 0;//計數器清零
	q.push(s);//起點入隊
	vis[s.x][s.y] = 1;//標記訪問
	
	while(!q.empty()){
		now = q.front();//取隊首元素進行擴展
		q.pop();
		
		if(MAP[now.x][now.y] - '0' == head){
			sum += now.step;
			s.x = now.x;
			s.y = now.y;
			return;
		}
		
		for(int i=0; i<4; i++){
			next.x = now.x + dir[i][0];
			next.y = now.y + dir[i][1];
			
			if(check(next)){//如果下一個狀態滿足約束條件 
				next.step = now.step + 1;
				q.push(next);//入隊 
				vis[next.x][next.y] = 1;//標記訪問 	
			}
		}		
	} 
	 
}
int main(void)
{
	memset(vis,0,sizeof(vis));	
	cin >> h >> w >> n;
	Node start;
	for(int i=0; i<h; i++){
		for(int j=0; j<w; j++){
			cin >> MAP[i][j];
			if(MAP[i][j] == 'S'){
				start.x = i;
				start.y = j;
			}
		}
	}
	
	sum = 0;
	head = 1;
	
	for(int i=0; i<n; i++){
		bfs(start);
		head++;
	}	
	cout << sum << endl;
		
	return 0;
}

/*
題意應該是從起點S開始
到1、2、3....n的最短距離
 輸入:第一行三個整數H(1 <= H <= 1000)、W(1 <= W <=1000)、N(1 <= N <= 9),之後H行W列爲地圖, “.“爲空地, ”X“爲障礙物,”S“爲老鼠洞, 1-N代表硬度爲1-N的奶酪的工廠。輸出最少用時。
*/

/*題意:
今年,JOI町的奶酪工廠開始生產奶酪,老鼠從巢中探出頭來。JOI町在東西南北進行劃分整理,各區劃爲巢、奶酪工廠、障礙物、空地之一。老鼠從巢出發,訪問所有的奶酪工廠,一個地喫奶酪。

這個城市有N個奶酪工廠,每個工廠都只生產一種奶酪。奶酪的硬度因工廠而異,正好有一個生產從1到N的奶酪的乾酪工廠。

老鼠最初的體力是1,每喫一個奶酪體力就會增加1。但是,老鼠不能喫比自己的體力還硬的奶酪。

老鼠可以在東西南北相鄰的區劃內移動1分鐘,但不能進入障礙物的區劃。也可以不喫芝士工廠而通過。請寫出尋求喫完所有奶酪所需的最短時間的程序。但是,老鼠喫奶酪所花的時間可以忽略不計。

輸入
輸入內容爲H+1行。第1行中以空格分隔的3個整數H,W,N(1 H 1000,1 W 1000,1 N 9)由空格分隔。從第2行到第H+1行,每一行都按照“S”,“1”,‘2’,.,‘9’,‘X’,‘.’‘寫下,“S”,’1‘,’2‘,.,’9‘,’X‘,’.‘組成的W字符串,每個文字都表示各分區的狀態。如果將從北部開始的第i個、從西開始的第j個區段記作(i,j)(1 i H,1 j W),第i+1行的第j個字符,在地塊(i,j)爲巢時爲‘S’,如果是障礙物,則爲“X”;如果是空地,則爲“.”,生產硬度爲1,2,.,9的乾酪的工廠,分別爲‘1’,‘2’,.,‘9’。在輸入時,巢和硬度爲1,2,.,生產N個奶酪的工廠各有1個。其他格子可以保證是障礙物或空地。老鼠可以保證可以喫到所有的奶酪。

輸出
輸出一個整數,表示喫完所有奶酪所花費的最短時間(分鐘)。
*/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章