程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> HDU1518 DFS

HDU1518 DFS

編輯:C++入門知識

傳送門

題意就是好多棍子,看能不能拼成正方形。主要注意的有幾點: 所有棍子都要用到,不能剩余輸入已經保證大於4根棍子了。所以無需判斷可能小於3根棍子的情況棍長的總數首先要是4的倍數,才能進行。否則直接輸出 “no”當前面前提滿足以後,再滿足3 根棍子拼好,就完工了。最後一根一定能拼好。 解法就是DFS------->深度優先搜索。DFS的思路就是一個圖沿著一條路走下去,當走不下去的時候就回溯到上一結點再去走沒有走過的岔路。 換算成數據結構的話,就要有一個“標記”來標記每個結點是否走過。DFS具體的實現方式,常見的一種就是:循環裡面嵌套遞歸,這也算是一個DFS的框架。而剩下的要補充的“題眼”(也就是關鍵的地方)是要轉移的 狀態
bool dfs(int count,int pos,int res)
這是本題中DFS算法的狀態。三個要素 count (已經拼好的棍子個數),pos (現在遍歷的第幾根棍子),res (要湊成目標長度剩余的長度) 當然在輸入數據以後要進行一次排序,從大到小排好依次遍歷。 我們要定義一個全局的變量 goal 代表你要湊齊的目標長度,換句話說就是總長度的 1/4 。
goal = sum/4;
標記的數組我們定義為used[21].值為 true 則標記過,即用過了。值為 false 則未用過。
//聲明,全局
bool used[21];
//初始化為false,main函數中
memset(used,false,sizeof(used));
下面看DFS函數的代碼:
bool dfs(int count,int pos,int res)
{
	if(count==3)//3根拼好就能保證都拼好
		return true;
	for(int i=pos;i//1:如果標記過就跳過下面過程
//2:先標記好true
//3:如果第i根棍子的長度和你剩余的所需要的棍子的長度一樣。那麼這根棍子就拼好了
//4:由//3可知,又拼好了一根,所以遞歸下一個棍子要拼的狀態,count+1。而pos初始化為0.從頭開始便利,res變為goal,即下一根棍子剩余的長度是全部所需長度。
//5:如果第i根棍子的長度小於目前所需的。那麼也把它加上 //6:下一個狀態。count不變,因為這根還沒拼好。pos = i+1,因為第i根已用。res-stick[i] 不言而喻了。 //7:前面如果滿足的話,就會返回true。而不執行這一句//7這句。如果能走到//7這句,那麼就是說前面的情況都不成功,也就是說這根棍子不能湊近去,所以要推翻加入這根棍子的方案
完整代碼:
#include 
#include 
using namespace std;
bool used[21];
int stick[21];
int t,goal;
bool cmp(int a,int b)
{
	return a>b;
}
bool dfs(int count,int pos,int res)
{
	if(count==3)//3根拼好就能保證都拼好
		return true;
	for(int i=pos;i>n;
	while(n--)
	{
		cin>>t;
		int sum=0;
		for(int i=0;i>stick[i];
			sum+=stick[i];
		}
		if(sum%4)
		{
			printf("no\n");
			continue;
		}
		goal = sum/4;
		memset(used,false,sizeof(used));
		sort(stick,stick+t,cmp);
		if(dfs(0,0,goal))//初始態
			printf("yes\n");
		else
			printf("no\n");
	}
	return 0;
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved