環狀序列( Circular Sequence, ACM/ICPC Seoul 2004, UVa1584)
阿新 • • 發佈:2020-12-07
技術標籤:演算法競賽入門經典(第二版)
問題:
長度為n的環狀串有n種表示法,分別為從某個位置開始順時針得到。例如,圖3-4的環狀串有10種表示:CGAGTCAGCT,GAGTCAGCTC,AGTCAGCTCG等。在這些表示法中,字典序最小的稱為"最小表示"。
輸入一個長度為n(n≤100)的環狀DNA串(只包含A、C、G、T這4種字元)的一種表示法,你的任務是輸出該環狀串的最小表示。例如,CTCC的最小表示是CCCT, CGAGTCAGCT的最小表示為AGCTCGAGTC。
思路:實際上,不用把以任何一個位置開頭的字串都進行比較,因為ATCG的字典序為ACGT,所以如果輸入串有A,那麼最小串肯定以A開頭,將所有以A開頭的進行比較即可。本來以為可以節省時間,但相對參考程式碼多了一個迴圈,還進行了字串的拼接,真是費力不討好。。。。。。
個人程式碼:
#include <bits/stdc++.h> using namespace std; int main() { int cnt; cin >> cnt; string str; while(cnt--) { cin >> str; //找到開始的字元 int len = (int)str.size(); char sta = 'T'; for (int i = 0; i < len; ++i) { if (str[i] < sta) sta = str[i]; } //遍歷 string mmin = str; for (int i = 1; i < len; ++i) { if (str[i] == sta) { string t = str.substr(i, len - i) + str.substr(0, i); if (t < mmin) mmin = t; } } cout << mmin << endl; } return 0; }
參考程式碼:
#include<stdio.h> #include<string.h> #define maxn 105 // 環狀串s的表示法p是否比表示法q的字典序小 int less(const char* s, int p, int q) { int n = strlen(s); for(int i = 0; i < n; i++) if(s[(p+i)%n] != s[(q+i)%n]) return s[(p+i)%n] < s[(q+i)%n]; return 0; // 相等 } int main() { int T; char s[maxn]; scanf("%d", &T); while(T--) { scanf("%s", s); int ans = 0; int n = strlen(s); for(int i = 1; i < n; i++) if(less(s, i, ans)) ans = i; for(int i = 0; i < n; i++) putchar(s[(i+ans)%n]); putchar('\n'); } return 0; }