HDU 1072 Nightmare

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1072

題意:

給一個矩陣,從2走到3,倒計時從6開始,看是否在倒計時結束前到達3,輸出最小步數。

規則:1可以走,0不可以走,遇到4,計數器重置爲6。

思路:這道題目看似不難,我卻做了好久,用的方法是DFS記憶化搜索,剛開始做只考慮了當走過的點的時間小於當前時間時,這個點就可以重複走,Wrong了幾次,後來才考慮到需要滿足兩個條件時,走過的點纔可以重複走:1、之前走過該點的時間小於當前時間 ;2、之前走過該點的步數大於當前步數(如果該點步數小於當前步數,再重複更新它的步數也沒有意義,還會影響最後的結果)。。


#include <iostream>
using namespace std;
#define N 10
int m,n,min_time;
struct Node{
	int time;//記錄到達該點的時間
	int vlue;//記錄該點的值
	int step;//記錄到達該點的步數
}mp[N][N];
void DFS(int x,int y,int step,int s)
{
	if(x<1||y<1||x>n||y>m||s<=0||mp[x][y].vlue==0||step>=min_time)
		return;
	if(mp[x][y].vlue==3)
	{
		min_time=min(min_time,step);
		return;
	}
	if(mp[x][y].vlue==4)
		s=6;
	if(mp[x][y].time>=s&&mp[x][y].step<=step)//關鍵代碼,優化
		return;
	mp[x][y].time=s;//更新該點的數據
	mp[x][y].step=step;
	DFS(x+1,y,step+1,s-1);
	DFS(x-1,y,step+1,s-1);
	DFS(x,y+1,step+1,s-1);
	DFS(x,y-1,step+1,s-1);
}
int main()
{
	int T,x1,y1;
	cin>>T;
	while(T--)
	{
		cin>>n>>m;
		for(int i=1;i<=n;i++)
			for(int j=1;j<=m;j++)
			{
				cin>>mp[i][j].vlue;
				mp[i][j].time=-1;
				mp[i][j].step=INT_MAX-3;
				if(mp[i][j].vlue==2)
					x1=i,y1=j;
			}
		min_time=INT_MAX;
		DFS(x1,y1,0,6);
		if (min_time != INT_MAX)
			cout << min_time << endl;
		else
			cout << "-1" << endl;
	}
	return 0;
}


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