hdu1226超級密碼 bfs

2022-05-20 12:13:11 字數 1927 閱讀 9309

題目大意是:尋找乙個五百位之內的c進製密碼,該密碼是n的正整數倍,而且只能用給定的數構成密碼,求這樣的密碼最小是多少。思路也不難想到,密碼的位數有限,我們可以通過廣度優先搜尋來搜尋目標狀態,通過已經拼接好的密碼再在最後新增一位就能產生擴充套件後的密碼,也就是層數增加一層,我們可以一層層搜尋,但是五百層是絕對不可能通過不剪枝的方法就能搜完的。剪枝的條件是:對於餘數相同的數,只讓最小的數入隊。

證明如下:

假設a=k1*n+q(0<=qk1,(即a,b餘數相同但是a大)那麼再進行擴充套件時,t*a+c=(t*k1)*n+t*q+c,t*b=(t*k2)*n+t*q+c,此時必有t*a>t*b,而且兩者模n的餘數一定是相等的,如果餘數都是0,那麼顯然t*b+c更加小,所以對於每一種餘數,我們只要儲存最小數的進行擴充套件就能保證最終第乙個出現的n倍數的數是最小的密碼。若選擇較大的數成功搜尋,則比它小的餘數相同的數按照同樣的步驟肯定能成為n的倍數。

**如下:

1 #include2

using

namespace

std;

3 typedef unsigned int

ui;4 typedef long

long

ll;5 typedef unsigned long

long

ull;

6#define pf printf

7#define mem(a,b) memset(a,b,sizeof(a))

8#define prime1 1e9+7

9#define prime2 1e9+9

10#define pi 3.14159265

11#define lson l,mid,rt<<1

12#define rson mid+1,r,rt<<1|1

13#define scand(x) scanf("%llf",&x)

14#define f(i,a,b) for(int i=a;i<=b;i++)

15#define scan(a) scanf("%d",&a)

16#define dbg(args) cout<<#args<<":"<17

#define inf 0x3f3f3f3f

18#define maxn 510

19#define maxm 5010

20int

n,m,t,c;

21int book[20

];22

bool

vis[maxm];

23struct

node;

27int getmod(node tmp)//

獲取餘數的函式 28

35return

ans;

36}

37node cur,ans;

38bool flag=false;39

void

print(node tmp)

4046 putchar('\n'

);47}48

49void

bfs()

5068

if(!vis[r])

6973}74

}75while(!q.empty())

7692

if(!vis[r]&&cur.len<500)93

97 cur.len--;98}

99}100}

101}

102int

main()

103123

if(n==0

)124

129else

130136

else pf("

give me the bomb please\n");

137}

138}

139return

0;

140 }

hdu1226 超級密碼 bfs

思路 因為n 5000 所以方案個數也只有5000個,可以用bfs來做。一開始挺糾結怎麼做,但是上網一看別的大牛的 一下子就恍然大悟豁然開朗,如同撥開雲霧見青天 o include include include include using namespace std const int maxn ...

HDU1226 超級密碼 BFS

由於n最大也只有5000,則對於列舉的密碼s,s n的狀態也只有5000種。所以每乙個列舉到的狀態,開兩個內容,乙個表示密碼的字串,乙個表示模n的餘數,當餘數為0的時候,說明找到密碼。include include include include include using namespace st...

hdu 1226 超級密碼 bfs

c 超級密碼 time limit 10000msmemory limit 32768kb64bit io format i64d i64u submit status description ignatius花了乙個星期的時間終於找到了傳說中的寶藏,寶藏被放在乙個房間裡,房間的門用密碼鎖起來了,在...