UVa140 Bandwidth 小剪枝+雙射小技巧+枚舉全排列+字符串的小處理


給出一個圖,找出其中的最小帶寬的排列。具體要求見傳送門:UVa140

這題有些小技巧可以簡化代碼的編寫。

本題的實現參考了劉汝佳老師的源碼,的確給了我許多啟發,感謝劉老師。

思路:

  1. 建立雙射關系:從字符A到字符Z遍歷輸入的字符串,用strchr函數將輸入中出現的字符找出,並將找出的字符進行編號,用letter和id分別存儲字符和對應的編號
  2. 降維:輸入中給出的,是類似於鄰接表形式的二維形式,如果我們用二維數據結構,將增加處理時對於輸出細節的處理難度,用 2個 vector將輸出降低到1維,簡化了計算Bandwidth時的代碼,實際上讓我們更加有的放矢
  3. 存儲必要信息——位置:數組pos每個下標代表字母編號,存儲的是對應的位置下標,便於計算時尋找位置。
  4. 剪枝:減去不必要的計算(雖然對於本題而言不是必須的)
  5. 庫函數的使用:memcpy,strchr,strlen,next_permutation的使用簡化了代碼,突出了邏輯部分。

代碼實現如下:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<vector>
 4 #include<algorithm> 
 5 using namespace std;
 6 
 7 const int maxn=10,inf=0x7fffffff;
 8 char letter[maxn], s[100];//字母,輸入序列 
 9 int id[256]; //字母的編號 
10 int p[maxn]; //全排列的遍歷數組 ,存儲的是每個字母的編號 
11 int pos[maxn];//記錄每個字母的位置,避免頻繁使用strchr 
12 
13 int main(){
14     while(scanf(" %s",&s),s[0]!='#'){
15         int len=strlen(s),n=0;
16         for(char ch='A';ch<='Z';ch++)if(strchr(s,ch)!=NULL){
17             letter[n]=ch;
18             id[ch]=n++;
19         }
20         vector<int> u,v;
21         for(int i=0;i<len;i++){
22             int t=i;//記錄起始節點 
23             i+=2;
24             while(i<len && s[i]!=';'){
25                 u.push_back(id[s[t]]);//加入起始節點 
26                 v.push_back(id[s[i]]);//加入起始節點的相鄰節點 
27                 i++;
28             }
29         }
30         //遍歷+剪枝
31         int bandwidth=0,res=inf;
32         int bestP[maxn];//存儲最終結果 
33         for(int i=0;i<n;i++)p[i]=i;
34         do{
35             bandwidth=0;//初始化別忘了 
36             for(int i=0;i<n;i++)pos[p[i]]=i;//記錄編號為pi的節點的位置 
37             for(int i=0;i<u.size();i++){
38                 bandwidth=max(bandwidth,abs(pos[u[i]]-pos[v[i]]));
39                 if(bandwidth>=res)break;//剪枝
40             }
41             if(bandwidth<res){
42                 memcpy(bestP,p,sizeof(p));//memcpy比較快 
43                 res=bandwidth;
44             }
45         }while(next_permutation(p,p+n));
46         for(int i=0;i<n;i++)printf("%c ",letter[bestP[i]]);
47         printf("-> %d\n",res);
48     }
49 }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM