1. 程式人生 > >HDU 1226 超級密碼 (BFS)

HDU 1226 超級密碼 (BFS)

余數 ace namespace des 開啟 panel mem bmi 約定

超級密碼

Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4523 Accepted Submission(s): 1468


Problem Description Ignatius花了一個星期的時間終於找到了傳說中的寶藏,寶藏被放在一個房間裏,房間的門用密碼鎖起來了,在門旁邊的墻上有一些關於密碼的提示信息:
密碼是一個C進制的數,並且只能由給定的M個數字構成,同時密碼是一個給定十進制整數N(0<=N<=5000)的正整數倍(如果存在多個滿足條件的數,那麽最小的那個就是密碼),如果這樣的密碼存在,那麽當你輸入它以後門將打開,如果不存在這樣的密碼......那就把門炸了吧.

註意:由於寶藏的歷史久遠,當時的系統最多只能保存500位密碼.因此如果得到的密碼長度大於500也不能用來開啟房門,這種情況也被認為密碼不存在.

Input 輸入數據的第一行是一個整數T(1<=T<=300),表示測試數據的數量.每組測試數據的第一行是兩個整數N(0<=N<=5000)和C(2<=C<=16),其中N表示的是題目描述中的給定十進制整數,C是密碼的進制數.測試數據的第二行是一個整數M(1<=M<=16),它表示構成密碼的數字的數量,然後是M個數字用來表示構成密碼的數字.兩個測試數據之間會有一個空行隔開.

註意:在給出的M個數字中,如果存在超過10的數,我們約定用A來表示10,B來表示11,C來表示12,D來表示13,E來表示14,F來表示15.我保證輸入數據都是合法的.

Output 對於每組測試數據,如果存在要求的密碼,則輸出該密碼,如果密碼不存在,則輸出"give me the bomb please".

註意:構成密碼的數字不一定全部都要用上;密碼有可能非常長,不要試圖用一個整型變量來保存密碼;我保證密碼最高位不為0(除非密碼本身就是0).

Sample Input 3 22 10 3 7 0 1 2 10 1 1 25 16 3 A B C

Sample Output 110 give me the bomb please CCB 題意為 用給定的數字,構造一個c進制並且是n倍數的數 因為要求要最小,我們可以把給定的數字先進行一個從小到大的排序 那麽用BFS,先搜索到的滿足條件的就一定是最小的 但是用BFS的話,如果直觀的將每個數儲存為一種狀態的話,我們在極限情況下就有16的500次方種狀態 顯然這樣是不行的,那麽應該思考能不能將其他的特征參數作為狀態呢? 我們可以發現,這道題是要求余數為0,那麽是n的多少倍是沒有什麽關系的 使用BFS的時候,是不斷的增加位數,那麽只要當前的余數只要相同,對後面的影響也就是相同的(從求余的過程可以發現) 所以我們可以把余數作為狀態,進行記錄,這樣的話就只有5000種狀態,滿足要求 這裏需要註意的是 當n不為0時,要讓首位不為0 當n為0時,如果最小的數字為0,輸出0,否則不存在 (不知道為什麽,這道題似乎認為0也是0的正整數倍) 代碼如下:
#include <stdio.h>
#include 
<algorithm> #include <iostream> #include <string.h> #include <queue> #include <cmath> #include <vector> #include <map> using namespace std; int vis[5100]; int t; int n,c,num; char ch; vector<char>V; //用來記錄可以使用的數字 struct node { string path; //bfs有時用string 記錄路徑很方便 int step; int mod; }; int get_mod(string x) //大數求余 { int ans=0; int tmp=x.size(); int h; for(int i=0;i<=x.size()-1;i++) { if(x[i]>=A) h=x[i]-A+10; else h=x[i]-0; ans=ans*c+h; ans=ans%n; } return ans; } string bfs() { memset(vis,0,sizeof(vis)); queue<node>Q; node a,next; a.step=0; a.path=""; a.mod=-1; Q.push(a); while(!Q.empty()) { a=Q.front(); Q.pop(); if(a.mod==0)return a.path; if(a.step>=500)break; next.step=a.step+1; for(int i=0;i<V.size();i++) { if(a.step==0&&V[i]==0&&n!=0)continue; next.path=a.path+V[i]; next.mod=get_mod(next.path); if(!vis[next.mod]) { vis[next.mod]=1; Q.push(next); } } } return ""; } int main() { scanf("%d",&t); string ans; while(t--) { V.clear(); scanf("%d%d",&n,&c); scanf("%d",&num); while(num--) { scanf(" %c",&ch); V.push_back(ch); } sort(V.begin(),V.end()); if(n==0) { if(V[0]==0)puts("0"); else puts("give me the bomb please"); continue; } ans=bfs(); if(ans=="")puts("give me the bomb please"); else cout<<ans<<endl; } return 0; }

HDU 1226 超級密碼 (BFS)