题目:长度为n的环状串有n种表示法,分别为从某个位置开始顺时针得到。例如,图3-4的环状串有10种表示:CGAGTCAGCT,GAGTCAGCTC,AGTCAGCTCG等。在这些表示法中,字典序最小的称为”最小表示”。
输入一个长度为n(n≤100)的环状DNA串(只包含A、C、G、T这4种字符)的一种表示法,你的任务是输出该环状串的最小表示。
输入: 2 CTCC CGAGTCAGCT
输出: CCCT
AGCTCGAGTC
提示:对于两个字符串,从第一的字符开始比较,当某一个位置的字符不同时,该位置字符较小的串,字典序小,如果一个字符串没有更多的字符,但是另一个字符串还没结束,则较短的字符串的字典序较小。
1.用char型字符串,比较,找最小【取模】
#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); int i; for(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, i;//ans表示目前为止,字典序最小串在输入串中的起始位置,然后不断更新ans int n = strlen(s); for(i = 1; i < n; i++) if(less(s, i, ans)) ans = i;//比较i与ans的大小,若真,将i的值辅助给ans for(i = 0; i < n; i++) putchar(s[(i+ans)%n]);//求得ans的位置然后从ans的位置往后输出s putchar('\n'); } return 0; }
2.用字符串的strcpy
#include<cstdio> #include<cstring> using namespace std; const int N = 150; char s[N], ans[N], c; int t, l; int main() { scanf ("%d", &t); while (t--) { scanf ("%s", s); l = strlen (s); strcpy (ans, s); for (int i = 0; i < l; ++i) { c = s[l - 1]; for (int j = l - 1; j >= 1 ; --j) s[j] = s[j - 1]; s[0] = c; if (strcmp (s, ans) < 0) strcpy (ans, s); } printf ("%s\n", ans); } }