1. 程式人生 > >1341 無序字母對

1341 無序字母對

說明 void 備註 很好 char 死胡同 得到 article 通過

難度:提高+/省選-

題目類型:圖論

提交次數:6

涉及知識:dfs/歐拉路徑

題目描述

給定n個各不相同的無序字母對(區分大小寫,無序即字母對中的兩個字母可以位置顛倒)。請構造一個有n+1個字母的字符串使得每個字母對都在這個字符串中出現。

輸入輸出格式

輸入格式:

第一行輸入一個正整數n。

以下n行每行兩個字母,表示這兩個字母需要相鄰。

輸出格式:

輸出滿足要求的字符串。

如果沒有滿足要求的字符串,請輸出“No Solution”。

如果有多種方案,請輸出前面的字母的ASCII編碼盡可能小的(字典序最小)的方案

輸入輸出樣例

輸入樣例#1:
4
aZ
tZ
Xt
aX
輸出樣例#1:
XaZtX

說明

【數據規模與約定】

不同的無序字母對個數有限,n的規模可以通過計算得到。

代碼:

 1 #include<iostream>
 2 using namespace std;
 3 int n;
 4 const int N = 52;
 5 int map[60][60];
 6 int du[60];
 7 char ans[2500];
 8 bool flag;
 9 int change(char a){
10     int askii = (int)(a);
11     if(askii<97){
12         return
askii-65; 13 } 14 else return askii-71; 15 } 16 char rechange(int x){ 17 if(x<=25) return char(x+65); 18 else return char(x+71); 19 } 20 void dfs(int x, int step){ 21 ans[step] = rechange(x); 22 if(step==n+1){ 23 flag = true; 24 return; 25 } 26 for
(int i = 0; i < 52; i++){ 27 if(map[x][i]>0){ 28 map[x][i]--; 29 map[i][x]--; 30 dfs(i,step+1); 31 if(flag) break; 32 map[x][i]++; 33 map[i][x]++; 34 } 35 } 36 if(!flag) ans[step] = 0; 37 } 38 int main(){ 39 cin>>n; 40 int i; 41 for(i = 1; i <= n; i++){ 42 char a, b; 43 cin>>a>>b; 44 int x = change(a); 45 int y = change(b); 46 map[x][y] = 1; 47 map[y][x] = 1; 48 du[x]++; 49 du[y]++; 50 } 51 int flag = 100; 52 int minn = 100; 53 int odd = 0; 54 for(i = 0; i <= 51; i++){ 55 if(du[i]!=0&&minn==100) minn = i; 56 if(du[i]%2 == 1){ 57 flag = min(flag, i); 58 odd++; 59 } 60 61 } 62 if(odd!=0&&odd!=2) { 63 cout<<"No Solution"<<endl; 64 return 0; 65 } 66 if(flag!=100) dfs(flag, 1); 67 else dfs(minn,1); 68 for(i = 1; i <= n+1; i++){ 69 cout<<ans[i]; 70 } 71 cout<<endl; 72 return 0; 73 }

備註:

歐拉路徑就是一筆畫,在圖中僅有0或2個奇數入度點時存在。昨天下午看了半天求歐拉路徑的算法,今天老師嘲諷一通說我看的是假的算法。。dfs+刪邊就可以了。雖然我很不願意接受,但這麽寫寫竟然是對的,而且效率還可以。

為什麽是對的很簡單。從一個奇數入度點出發,如果全是偶數入度點,就從最小的點開始,dfs,走到無路可走時就找到了一個解。註意一定要回溯(否則走入一條死胡同就結束了),肯定不能一到某個點就輸出這個點(此時不一定走的就是正確的路)這也是dfs加一個step參量的必要性(最後一次更新一定是正解)(回溯到這個點說明上一次從這個點出去選擇的方向走不完圖,所以換個方向走)。

字典序很好辦。從小到大搜就可以了。

後來codevs過了,洛谷最後一個點過不了。看了一眼討論,發現ans數組開小了。n的規模可以算,應該是52*52,開成2500就過了。

1341 無序字母對