1. 程式人生 > >DFS【洛谷P1092】

DFS【洛谷P1092】

獻上題目連結:https://www.luogu.org/problemnew/show/P1092

 

又碰到了這種帶有模擬思路的DFS,在以前的印象裡,DFS都是與圖論搜尋掛上鉤的。原來DFS的應用這麼廣泛,在洛谷上刷了幾個DFS,也算對於這種演算法有了新的認識吧。

拿到題目,我想直接全排列搞一波試一試,受限於教室裡面的環境以及自己的模擬能力,我也就只是想了想。寫了一半發現寫不出來。(我怎麼可以這麼蒻)

不廢話了,直接說思路:

這個題目是一個思路很清晰的DFS,因為是加法豎式,而且我也沒有reverse,所以直接從第1行第n列開始DFS,(第一行第n列就是豎式的左上角的那個字母,大家應該能想明白)。如果沒找到第3行,就在該列繼續往下找,找到了第3行,就重新找第1行第x-1列。(方向是從上到下,從右往左)

因為算式的三行長度相等,所以判斷成不成立的條件就是第1列的進位是0。

這樣就可以很顯然的寫出程式碼了,但是可能會TLE。

我們在判斷等式是否成立時,每一步都是可以判斷的,如果有一步不成立就可以直接return掉了。這樣可能大概應該會剪掉不少枝。

 

空口無憑,上程式碼!

#include <bits/stdc++.h>
using namespace std;
const int maxn = 30;
int n;
string str[5];
int num[maxn];
bool vis[maxn];
int getid(char ch)
{
	return ch-'A'+1;
}
void init()
{
	memset(num,-1,sizeof(num));
	memset(vis,0,sizeof(vis));
}
void dfs(int x,int y,int t)
{
	if(x==0 && t==0)
	{
		for(int i=1;i<=n;i++)
		{
			cout<<num[i];
			if(i<n)
			{
				cout<<" ";
			}
		}
		cout<<endl;
		return;
	}
	for(int i=x-1;i>=1;i--)
	{
		int w1 = num[getid(str[1][i])];
		int w2 = num[getid(str[2][i])];
		int w3 = num[getid(str[3][i])];
		if(w1==-1 || w2==-1 || w3==-1)
		{
			continue;
		}
		if((w1+w2)%n!=w3 && (w1+w2+1)%n!=w3)
		{
			return;
		}
	}
	if(num[getid(str[y][x])] == -1)
	{
		for(int i=n-1;i>=0;i--)
		{
			if(!vis[i])
			{
				if(y!=3)
				{
					num[getid(str[y][x])] = i;
					vis[i] = 1;
					dfs(x,y+1,t);
					num[getid(str[y][x])] = -1;
					vis[i] = 0;
				}
				else
				{
					int w = num[getid(str[1][x])] + num[getid(str[2][x])] + t;
					if(w%n != i)
					{
						continue;
					}
					num[getid(str[y][x])] = i;
					vis[i] = 1;
					dfs(x-1,1,w/n);
					num[getid(str[y][x])] = -1;
					vis[i] = 0;
				}
			}
		} 
	}
	else
	{
		if(y!=3)
		{
			dfs(x,y+1,t);
		}
		else
		{
			int w = num[getid(str[1][x])] + num[getid(str[2][x])] + t;
			if(w%n != num[getid(str[3][x])])
			{
				return;
			}
			dfs(x-1,1,w/n);
		}
	}
}
int main()
{
	while(cin>>n)
	{
		init();
		for(int i=1;i<=3;i++)
		{
			cin>>str[i];
			str[i].insert(0,"#");
		}
		dfs(n,1,0);
	}
	return 0;
}

PS:真的好蒻,DFS原來有這麼多玩法。