1. 程式人生 > >[NOI OJ]6044:鳴人和佐助

[NOI OJ]6044:鳴人和佐助

6044:鳴人和佐助

總時間限制: 
1000ms
記憶體限制: 
65536kB
描述

佐助被大蛇丸誘騙走了,鳴人在多少時間內能追上他呢?

已知一張地圖(以二維矩陣的形式表示)以及佐助和鳴人的位置。地圖上的每個位置都可以走到,只不過有些位置上有大蛇丸的手下,需要先打敗大蛇丸的手下才能到這些位置。鳴人有一定數量的查克拉,每一個單位的查克拉可以打敗一個大蛇丸的手下。假設鳴人可以往上下左右四個方向移動,每移動一個距離需要花費1個單位時間,打敗大蛇丸的手下不需要時間。如果鳴人查克拉消耗完了,則只可以走到沒有大蛇丸手下的位置,不可以再移動到有大蛇丸手下的位置。佐助在此期間不移動,大蛇丸的手下也不移動。請問,鳴人要追上佐助最少需要花費多少時間?

輸入
輸入的第一行包含三個整數:M,N,T。代表M行N列的地圖和鳴人初始的查克拉數量T。0 < M,N < 200,0 ≤ T < 10後面是M行N列的地圖,其中@代表鳴人,+代表佐助。*代表通路,#代表大蛇丸的手下。
輸出
輸出包含一個整數R,代表鳴人追上佐助最少需要花費的時間。如果鳴人無法追上佐助,則輸出-1。
樣例輸入
樣例輸入14 4 1#@##**#####+****樣例輸入24 4 2#@##**#####+****
樣例輸出
樣例輸出16樣例輸出24
解題思路:
迷宮內求最少的時間,很明顯的bfs或dp題型。資料量並不大。本蒟蒻本想在同學面前秀一下狀壓dp,結果仔細一看……老實用bfs吧。
這裡比普通的二維迷宮加了一個時間,在不同的時間走到同一個格點,是不同的情況,擴展出來的新元素也會不同。所以我們需要在
標記陣列中加一維用於記錄時間。
如果你不用queue的話,最好自己寫一個函式來模擬,尤其是這種用到結構體的bfs。否則會程式碼很凌亂。
注意一下p和t加1減1之類的,我這個程式碼應該不需要考慮了。
蒟蒻一隻,有錯誤之處還請諒解。歡迎提問-.-
程式碼如下:
#include<cstdio>
#include<queue>
using namespace std;
char g[205][205];
int dic[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int sx,sy,ex,ey;
int tmax,pmin;
int m,n;
bool b[205][205][15];
const int Inf=999999;
struct squ
{
	int x,y,p,t;
	squ(int xa,int ya,int pa,int ta):x(xa),y(ya),p(pa),t(ta){};//建構函式的一種型別:初始化列表。所以oop還是要學的
};
queue<squ> q;
void bfs() 
{
//初始化
	int t=0,p=0,nx=0,ny=0;
	squ temp(sx,sy,0,tmax);
	q.push(temp);
while(!q.empty())
	{
//獲取隊首元素後彈出
		temp=q.front();
		t=temp.t;
		p=temp.p;
		if(temp.x==ex && temp.y==ey)
		{
			pmin=temp.p;
			return;
		}
		q.pop();
//四方向列舉
		for(int i=0;i<4;i++)
		{
			nx=temp.x+dic[i][0];
			ny=temp.y+dic[i][1];
			if(!b[nx][ny][t] && nx>0 && nx<=m && ny>0 && ny<=n && g[nx][ny] != '#' )
			{
				q.push(squ(nx,ny,p+1,t));
				b[nx][ny][t]=true;
			}
//由於C++運算子的短路現象,在&&中,當t>0不符合時,!b[nx][ny][t-1]不會執行,不必擔心越界問題。
			if(t>0 && !b[nx][ny][t-1] && nx>0 && nx<=m && ny>0 && ny<=n && g[nx][ny] == '#')
			{
				q.push(squ(nx,ny,p+1,t-1));
				b[nx][ny][t-1]=true;
			}
		}
	}
}
int main()
{
	freopen("data.txt","r",stdin);//良好的除錯習慣
	scanf("%d%d%d",&m,&n,&tmax);//儘量使用scanf和printf,這樣更快。當然你要優化輸入我。。。Orz
	pmin = Inf;
	getchar();
	for(int i = 1;i <= m;i++)
	{	
		for(int j = 1;j <= n;j++)
		{
			scanf("%c",&g[i][j]);
			if(g[i][j] == '+')
			{
				ex = i;
				ey = j;
			}
			else if(g[i][j] == '@')
			{
				sx = i;
				sy = j;
			}
		}
		getchar();
	}
	if(sx==ex && sy == ey)
	{
		printf("0");
		return 0;
	}
	bfs();
	if(pmin==Inf)
		printf("-1");
	else
		printf("%d",pmin);
	return 0;
}


相關推薦

[NOI OJ]6044:人和

6044:鳴人和佐助檢視提交統計提問總時間限制: 1000ms記憶體限制: 65536kB描述佐助被大蛇丸誘騙走了,鳴人在多少時間內能追上他呢?已知一張地圖(以二維矩陣的形式表示)以及佐助和鳴人的位

人和(含特殊的狀態的BFS)

024:鳴人和佐助 檢視 提交 統計 提問 總時間限制:  1000ms 記憶體限制:  65536kB 描述 佐助被大蛇丸誘騙走了,鳴人在多少時間內能追上他呢? 已知一張地圖(以二維矩陣的形式表示)以及佐助和鳴人的位置。地圖上的每個位置都可以走到

openjudge 人和(bfs+優先佇列)

問題分析 問鳴人追上佐助所需的最少時間,打敗大蛇的手下不花費時間但是消耗查克拉,移動一個單位花費11個單位時間。 這道題在普通bfsbfs的基礎上增加了狀態的一個屬性,唯一需要考慮的就是我們應該優先走消耗查克拉少的路徑還是消耗查克拉多的路徑,明顯為了走的更遠

【遞迴+BFS】百練4115:人和

有幾點要總結的:1、做題時候上一道是dfs,結果先入為主,直接用的dfs。做是做出來了但是超時。dfs:判斷解是否存在性bfs:找到最優解,這道題是要找到時間最短的,最先遇到佐助的路徑一定是最優路徑,因此應該用bfs。同時他還增加了鑽石數的限定。2、然而這道題有煩人的查克拉問題,可能最短路會由於全是守衛,所以

百練 4115 人和

#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace s

poj 4115:人和

4115:鳴人和佐助 總時間限制: 1000ms 記憶體限制: 65536kB描述 佐助被大蛇丸誘騙走了,鳴人在多少時間內能追上他呢? 已知一張地圖(以二維矩陣的形式表示)以及佐助和鳴人的位置

[openjudge-搜尋]廣度優先搜尋之人和

題目描述描述佐助被大蛇丸誘騙走了,鳴人在多少時間內能追上他呢?已知一張地圖(以二維矩陣的形式表示)以及佐助和鳴人的位置。地圖上的每個位置都可以走到,只不過有些位置上有大蛇丸的手下,需要先打敗大蛇丸的手下

4115:名人和 bfs

點選開啟連結http://bailian.openjudge.cn/2016acm/11/ 學長部落格上的一道bfs;   總時間限制: 1000ms 記憶體限制: 65536kB 描述     佐助被大蛇丸誘騙走了,鳴人在多少時間內能追上

BFS:noi6044人與

span col cstring str 基本 數組 左右 初始 ges PS:一道XX到我心態崩潰的好(傻逼)題。 先粘題目: 佐助被大蛇丸誘騙走了,鳴人在多少時間內能追上他呢? 已知一張地圖(以二維矩陣的形式表示)以及佐助和鳴人的位置。地圖上的每個位置都可以走到

【BFS】人與

bsp struct 全部 main pac pri image iostream cnblogs 總時間限制:1000ms內存限制:65536kB描述 佐助被大蛇丸誘騙走了,鳴人在多少時間內能追上他呢? 已知一張地圖(以二維矩陣的形式表示)以及佐助和鳴人的位置。地

廣搜之人與

#include<iostream> #include <stdio.h> #include <memory.h> #include <queue> using namespace std; int M,N,T; char Ma

人與 poj

典型的bfs 技巧在於設定了G[x][y]來進行剪枝,減少了執行時間與空間。即如果在某一點,已經有大於當前的查克拉的路線,就不再繼續走這一點。 #include <iostream> #include <cstring> #include <c

Openjudge-4115-和鳴人

這一題是一道廣搜的題目,首先我們通過讀入字串讀入每一行,然後順帶找到鳴人的位置。 然後我們初始化之後,就進行廣搜,還是廣搜的格式,但是要壓入佇列的條件我們可以稍微變一變,我們可以直接判斷下一個要走的點,是星號或者是加號,我們就判斷是否走過這一點是否走過。 我們判斷的依據是,假設我們走這一點,

的師父是成龍!有圖為證!

導讀:   此貼由熱心網友天使之盟提供 ↓分享此帖↓道具   By:天使之盟「市民」 ------------------------------------   【發信編輯/回覆】發貼時間:

Openjudge 和鳴人(BFS+雙變數)

已知一張地圖(以二維矩陣的形式表示)以及佐助和鳴人的位置。地圖上的每個位置都可以走到,只不過有些位置上有大蛇丸的手下,需要先打敗大蛇丸的手下才能到這些位置。鳴人有一定數量的查克拉,每一個單位的查克拉可以打敗一個大蛇丸的手下。假設鳴人可以往上下左右四個方向移動,每移動一個

NOI OJ】8783 單詞接龍

8783:單詞接龍 總時間限制: 1000ms 記憶體限制: 65536kB 描述 單詞接龍是一個與我們經常玩的成語接龍相類似的遊戲,現在我們已知一組單詞,且給定一個開頭的字母,要求出以這

NOI OJ】1818 紅與黑

1818:紅與黑 總時間限制: 1000ms 記憶體限制: 65536kB 描述 有一間長方形的房子,地上鋪了紅色、黑色兩種顏色的正方形瓷磚。你站在其中一塊黑色的瓷磚上,只能向相鄰的黑色瓷磚移

51nod oj 1072 威夫遊戲 1185 威夫遊戲 V2【威夫博奕】

威佐夫博奕(Wythoff Game):有兩堆各若干個物品,兩個人輪流從某一堆或同 時從兩堆中取同樣多的物品,規定每次至少取一個,多者不限,最後取光者得勝。     這種情況下是頗為複雜的。我們用(ak,bk)(ak ≤ bk ,k=0,1,2,...,n)表示 兩堆物品的數量並稱其為局勢,如果甲面對(0,0

九度OJ 題目1013:開門人和關門人

 一.題目描述:     每天第一個到機房的人要把門開啟,最後一個離開的人要把門關好。現有一堆雜亂的機房簽到、籤離記錄,請根據記錄找出當天開門和關門的人。 輸入:     測試輸入的第一行給出記錄的總天數N ( N> 0 ),下面列出了N天的記錄。    

noi 162 post office dp

ons style freopen pri class pre 現在 pen mes 大致題意: 有v個村莊,每個村莊有各自的位置,且每個位置互不相同。現在要在村莊上設立P個郵局,使每個村莊到最近的郵局的距離之和最小。 分析: 定義狀態d[