洛谷P1341 無序字母對

2021-10-02 14:15:28 字數 1528 閱讀 2301

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

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

各不相同的無序字母對總數有限,有52*51/2=1326種,這是n的規模。

此題的建模是圖論,給出的無序字母對相當於圖的邊,圖的頂點上是字母,這樣構造出來n+1長度的字串就必然要包含所有邊(而乙個頂點可以經過多次),簡單判斷後這是尋找圖的尤拉通路/迴路問題。

尤拉通路:包含圖上所有的邊但不首尾相連

尤拉迴路:包含圖上所有邊且首尾相連

用dfs即可找出尤拉路,對邊記錄vis即可,如果找到了盡頭,但是仍然有邊未被選中,則回溯

#include

"cstdlib"

#include

#include

#include

#include

#include

#include

#include

using

namespace std;

vector<

int>edge[60]

;//存邊,edge[i]下包含從i出發的所有邊,i編號:a1,b2...z26,a27...z52

int vis[60]

[60];

//記錄邊是否被用過,vis[j][i]表示這條邊已經被用

int in[60]

;//記錄連線邊數,為了判斷solution

int used =0;

//表示已經選中used條邊

int n;

//總邊數

char ans[

2000];

int ptr =0;

int flag =0;

//已經找到解

char

num_to_char

(int num)

//將1~52的數字轉成對應的字母

void

dfs(

int s)

int t;

//表示下乙個頂點

for(

int i =

0; i < edge[s]

.size()

; i++

)//按字典序,能保證較小

}int

main()

int cnt =0;

//度為奇數點的個數

for(

int i =

1; i <=

52; i++

)sort

(edge[i]

.begin()

, edge[i]

.end()

);}if

(cnt ==0)

//從第一位開始保證字典序小

} cout << ans;

}else

if(cnt==2)

//尤拉通路情況

else

return0;

}

洛谷 P1341 無序字母對

這道題第一眼以為是一道字串的題,但細想一下是一道求尤拉路的圖論題。把每一對對應關係看成一條邊,本題即求這張圖上是否存在乙個尤拉迴路或尤拉路,並要求字典序最小的方案,那麼我們在dfs的時候就要從該點所連的最小的點開始便利,並將所得的結果存在乙個陣列中,最後逆序輸出。include include in...

洛谷P1341 無序字母對

題目鏈結 根據題意,只有在每兩個相鄰的字母都構成乙個要求的無序字母對時,才能滿足要求,我們不妨將每個字母看成乙個節點,每個無序字母對看成乙個無向邊,我們要從乙個點出發,不重複地走完所有的邊,所走的路徑上的點構成的字串即為乙個合法的解 這就轉化成了求一條字典序最小的尤拉路徑 字典序就用堆搞一下就行了 ...

洛谷P1341 無序字母對

題目大意 見原題目描述,說的很清楚。演算法 圖論 尤拉路徑 思路 題目資料中沒有重複條件,因此成功得到解有兩種可能。n個點,n條路徑,形成尤拉迴路 沒有奇數點 n 1個點,n條路徑,形成尤拉路徑 只有2個奇數點 因此先判斷是否有解,如果有就用dfs搜尤拉路徑 迴路 即可。我這裡給每個字母都進行了編號...