題目大意是:尋找乙個五百位之內的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 #include2using
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花了乙個星期的時間終於找到了傳說中的寶藏,寶藏被放在乙個房間裡,房間的門用密碼鎖起來了,在...