leetcode33.搜尋旋轉排序陣列
阿新 • • 發佈:2021-11-03
按照題意建圖,然後要求尤拉路徑,對一個尤拉路徑的判定
歐拉回路屬於尤拉路徑,而尤拉路徑要求遠比歐拉回路要求低。
無向圖 當且僅當圖中有兩點度數為奇數,其他點度數皆為偶數且聯通。
有向圖 當且僅當其中一個頂點的入度少於出度1,而另一點出度少於入度1,圖聯通時。
至於為什麼要倒著存,可以這樣解釋
input:
5
xx
xa
aa
ab
bx
output 50pts:
aabxax
output 100pts:
aabxxa
可以發現,50pts程式碼會貪心地挑較小結點訪問,當訪問到倒數第三個字母x時,會毫不猶豫地前往a,而不管這樣做是否能遍歷完,因此走到a無路可走了,又回到x遍歷另外一個x,從而得到一個錯誤的答案
而100pts程式碼的好處在於,它是在遍歷結束後將該結點逆序存入答案中,這就保證了無路可走的節點a一定是該序列的結尾(因為如果該結點還能繼續訪問,它就一定在那些能繼續訪問的點的前面),然後回到倒數第三個字母x尋找下一個x訪問。此處不用擔心x是否也是一個結尾(那樣就無解了),因為通過遞迴前的判斷,這張圖中一定存在尤拉路,也就是隻有一個終點
const int N=10007; int m; std::string s; int g[N][N]; int ot[N]; char a[N]; int ans; inline void print(){ drp(i,ans,1){ cout<<a[i]; } cout<<'\n'; } inline void dfs(int x){ rep(j,1,150){ if(g[x][j]){ --g[x][j]; --g[j][x]; dfs(j); } } a[++ans]=x; } int main(){ std::ios::sync_with_stdio(false); cin>>m; rep(i,1,m){ cin>>s; ++g[s[0]][s[1]]; ++g[s[1]][s[0]]; ++ot[s[0]]; ++ot[s[1]]; } int cnt(0),a(0); rep(i,1,150){ if(ot[i]&1){ ++cnt; if(!a) a=i; } } if(!a) { rep(i,1,150){ if(ot[i]) { a=i; break; } } } if(cnt&&cnt!=2){ puts("No Solution"); return 0; } dfs(a); if(ans!=m+1){ puts("No Solution"); return 0; } print(); return 0; }
本文來自部落格園,作者:{2519},轉載請註明原文連結:https://www.cnblogs.com/QQ2519/p/15573657.html