算法提高 士兵排隊問題
時間限制:1.0s 內存限制:256.0MB
試題
有N個士兵(1≤N≤26),編號依次為 A,B,C,…,隊列訓練時,指揮官要把一些士兵從高到矮一次排成一行,但現在指揮官不能直接獲得每個人的身高信息,只能獲得“P1比P2高”這樣的比較 結果(P1、P2∈A,B,C,…,Z,記為 P1> P2),如”A> B”表示A比B高。
請編一程序,根據所得到的比較結果求出一種符合條件的排隊方案。
(注:比較結果中沒有涉及的士兵不參加排隊)
輸入要求
比較結果從文本文件中讀入(文件由鍵盤輸入),每個比較結果在文本文件中占一行。
輸出要求
若輸入數據無解,打印“No Answer!”信息,否則從高到矮一次輸出每一個士兵的編號,中間無分割符,並把結果寫入文本文件中,文件由鍵盤輸入:
樣例輸入
A>B
B>D
F>D
樣例輸出
AFBD
1 /* 2 問題 拓撲排序 3 解題思路 使用隊列的拓撲排序解法 4 坑點 1、注意吃掉換行 2、注意字符和數字的轉換 3、寫的時候注意用一種全覆蓋的方法 5 4、No answer!中間只有一個空格,輸入關系中一個大寫字母加“>”號加一個大寫字母 6 5、輸入存在重復邊,注意不要增加重復的入度 7 */ 8 #include<cstdio> 9 #include<iostream> 10 #include<queue> 11 #include<cstring> 12 #include<vector> 13 using namespace std; 14 15 16 17 int cou,map[31][31],book[31],deg[31]; 18 vector<char> ans; 19 int toposort(); 20 21 int main() 22 { 23 char u,v; 24 memset(map,0,sizeof(map)); 25 memset(deg,0,sizeof(deg)); 26 int i; 27 cou=0; 28 while(scanf(" %c>%c",&u,&v) != EOF){ 29 //cout<<u<<"->"<<v<<endl; 30 if( map[u - 'A'][v - 'A'] ) continue;//重復的邊跳過 31 map[u - 'A'][v - 'A']=1; 32 book[u - 'A']=book[v - 'A']=1;//該字母出現 33 deg[v - 'A']++; 34 } 35 36 /*for(i=0;i<31;i++){ 37 if(book[i]) 38 printf("%c的入度為%d\n",i+'A',deg[i]); 39 } 40 for(i=0;i<31;i++){ 41 if(book[i]) 42 printf("%c出現過\n",i+'A'); 43 }*/ 44 ans.clear(); 45 if(toposort()){ 46 for(i=0;i<ans.size();i++){ 47 printf("%c",ans[i]); 48 } 49 printf("\n"); 50 } 51 else 52 printf("No Answer!\n"); 53 return 0; 54 } 55 56 int toposort() 57 { 58 queue<int> q; 59 int x,t=0,i,j; 60 for(i=0;i<31;i++){ 61 if(book[i]){ 62 cou++; 63 if(deg[i] == 0) //出現過且入度為0 64 q.push(i); 65 } 66 } 67 68 while(!q.empty()){ 69 x=q.front(); 70 q.pop(); 71 t++; 72 ans.push_back(x + 'A'); 73 //printf("%c\n",x + 'A'); 74 75 for(i=0;i<31;i++){ 76 if(book[i] && map[x][i]){ 77 deg[i]--; 78 if(deg[i] == 0) 79 q.push(i); 80 } 81 } 82 } 83 84 if(t == cou) return 1; 85 return 0; 86 }
