环状序列
题目
长度为n的环状串有n中表示法,分别为从某个位置开始顺时针得到。
例如,图中的环状串有10中表示:CGAGTCAGCT, GAGTCAGCTC,
AGTCAGCTCG等在这些表示法中,字典序最小的称为“最小表示”。
输入一个长度为n(n<=100)的环状DNA串(只包含A、C、G、T这4中字符)的一种表示法,
你的任务时输出该环状串的最小表示。例如,CTCC的最小表示是CCCT,
CGAGTCAGCT的最小表示是AGCTCGAGTC。
分析
字典序:所谓字典序,就是字符串在字典中的顺序。
一般的对于两个字符串,从第一个字符开始比较,当某一个位置的字符不同时,该位置字符较小的串,字典序较小(例如,abc比bcd小);
如果其中一个字符串已经没有更多字符,但另一个字符串还没结束,则较短的字符串的字典序较小(例如,hi比history小)。
字典序的概念可以推广到任意序列,例如,1,2,4,7比1,2,5小。
学会了字典序的概念之后,对于本题,就像求n个元素中的最小值一样,用变量ans表示目前为止,字典序最小串在输入串中的起始位置,
然后不断更新ans。
c实现
#include<stdio.h> #include<string.h> #define maxn 105 //环状串s的表示法p是否比表示法q的字典序小 //若p的字典序小于q的字典序则返回1(true),否则返回0(false) 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; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现