环状序列( Circular Sequence, ACM/ICPC Seoul 2004, UVa1584)
作者:互联网
问题:
长度为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;
}
标签:Seoul,Sequence,int,ACM,表示法,++,len,str,环状 来源: https://blog.csdn.net/qq_42283621/article/details/110748036