1. 程式人生 > >HDU 1016(DFS素數環)

HDU 1016(DFS素數環)

初看很難 其實很簡單的一道題目

大致就是1-n 把這n個數填到一個環裡 相鄰的和是素數 求怎麼填

我開始的時候 覺得要順時針還要逆時針 心想繁瑣 就直接找了部落格 然後部落格的程式碼異常簡潔啊

突然領悟了 逆時針的只要水平翻轉一下一樣是個順時針的 也就是說 這個逆時針已經在所有情況裡了

然後這個題 其實也是那種 案例過了就很難再有問題的題

問題是我開始的時候的打的那一邊怎麼都過不了案例 為什麼呢 因為vis標錯物件了

我們的程式碼思路很簡單 num是層數 是數字安放的位置 i是數字 一個個看這個數字可不可以放在這裡 如果遍歷一遍1-n所有數字都不可以放在這 那麼就返回上一層 不然就繼續下一個位置

其中就需要判斷一個數字有沒有放過 而我判斷的是這個位置有沒有數字存在 這需要判斷嗎 不需要……所以找了半天錯了

 

然後 然後我reac 再次驚訝到了 我覺得我理解了比較OK了 然而 當然對比一下昨天的程式碼就可以很明顯的知道問題

dfs傳引數的時候 傳的是num 而我一旦使用了自增 那麼在這一層的num都會受到影響 所以 不可以!

開始我用的num++(日常秀逗) 後來驚呼 傳進去的都是自增前的 然後換成++num 結果也不ok 原因如上

希望能長點記性把

#include <iostream>
#include <string>
#include <cstring>
#include <sstream>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <cmath>
using namespace std;

int isp[50];
int a[50], vis[50];
int n;

void pri()
{
	for (int i = 2; i < 50; i++)
	{
		if (isp[i] == 0)
		{
			for (int j = i; i*j < 50; j++)
			{
				isp[j*i] = 1;
			}
		}
	}
}

void dfs(int num)
{
	if (n == num && isp[a[0] + a[n - 1]] == 0)
	{
		for (int i = 0; i < n; i++)
		{
			cout << a[i] << (i == n - 1 ? "\n" : " ");
		}
	}
	else
	{
		for (int i = 2; i <= n; i++)
		{
			if (vis[i] == 0 && isp[i + a[num - 1]]==0)
			{
				vis[i] = 1;
				a[num] = i;
				dfs(num+1);//絕對不能用++ 自增
				vis[i] = 0;
			}
		}
	}
}
int main()
{
	pri();
	int cas = 0;
	while (cin >> n)
	{
		printf("Case %d:\n", ++cas);
		memset(vis, 0, sizeof(vis));
		memset(a, 0, sizeof(a));
		a[0] = 1;
		dfs(1);
		cout << endl;
	}
	system("pause");
	return 0;
}