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

無序字母對

fine body sam -- sample 分享 圖片 scan 條件

題目描述

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

輸入輸出格式

輸入格式:

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

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

輸出格式:

輸出滿足要求的字符串。

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

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

輸入輸出樣例

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

說明

【數據規模與約定】

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

首先看題目要求,要求用n+1個字符表示出n個字母對(無序)
那麽仔細想一下,首尾相接也就是一個環
考慮n個字母對就相當於n條邊,字母相當於點
而又不重復,我們想到了什麽?
對,歐拉路(歐拉回路)

我們在字母對之間建無向邊,然後求歐拉路(歐拉回路),就是答案
但是要註意,求歐拉路(歐拉回路)的首要條件是這個圖已知是歐拉圖
對於判無解的情況,即這個圖不是歐拉圖。

判斷無向圖是不是歐拉圖可以參見我的OK

技術分享圖片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cmath>
 5
#include<queue> 6 #include<map> 7 #define ll long long 8 #define DB double 9 #define eps 1e-3 10 #define inf 1847524821 11 #define u p[s[0]] 12 #define v p[s[1]] 13 using namespace std; 14 inline int read() 15 { 16 int x=0,w=1;char ch=getchar(); 17 while(!isdigit(ch)){if(ch==-
) w=-1;ch=getchar();} 18 while(isdigit(ch)) x=(x<<3)+(x<<1)+ch-0,ch=getchar(); 19 return x*w; 20 } 21 const int N=1020; 22 int n,du[N],a[N][N],ans[N],k,S; 23 map<char,int>p; 24 map<int,char>h; 25 char s[30]; 26 void dfs(int x) 27 { 28 for(int i=1;i<=256;++i) 29 if(a[x][i]>=1) 30 { 31 a[x][i]--;a[i][x]--; 32 dfs(i); 33 } 34 ans[++k]=x; 35 } 36 int main() 37 { 38 for(int i=0;i<=255;++i)p[char(i)]=i+1,h[i+1]=char(i); 39 n=read(); 40 for(int i=1;i<=n;++i) 41 { 42 scanf("%s",s); 43 a[u][v]=a[v][u]=1; 44 du[u]++;du[v]++; 45 } 46 int fg=0; 47 for(int i=1;i<=256;++i) 48 { 49 if(du[i]==0) continue; 50 if(S==0 && du[i]%2==0) S=i; 51 if(du[i]%2) fg=1; 52 } 53 if(fg) 54 { 55 fg=0; 56 for(int i=1;i<=256;++i) 57 { 58 if(du[i]==0) continue; 59 if(du[i]%2) fg++; 60 } 61 if(fg && fg>2){printf("No Solution");return 0;} 62 S=0;fg=0; 63 for(int i=1;i<=256;++i) 64 { 65 if(du[i]==0) continue; 66 if(du[i]%2 && !fg) fg++,S=i; 67 } 68 } 69 dfs(S); 70 if(k<n+1) printf("No Solution"); 71 else{ 72 for(int i=k;i>=1;--i) 73 cout<<h[ans[i]]; 74 } 75 return 0; 76 }
View Code

(?′?‵?)I L???????

無序字母對