例題3-6 環狀序列ACM程式碼+註釋
阿新 • • 發佈:2020-12-19
例題3-6 環狀序列(ACM2004)
**看了很久才把書上的程式碼看懂,別看我是c++寫的,其實和c幾乎沒有區別。
程式碼後面附上詳細註釋,希望能幫助和我一樣的新人理解書上的程式碼。**
【題目描述】
長度為n的環狀串有n種表示法,分別為某個位置開始順時針得到。例如,圖中的環狀串有10種表示:
CGAGTCAGCT,GAGTCAGCTC,AGTCAGCTCG等。在這些表示法中,字典序最小的稱為“最小表示”。
輸入一個長度為n(n<=100)的環狀DNA串(只包含A、C、G、T這4種字元)的一種表示法,你的任務是輸出該環狀串的最小表示。例如,CTCC的最小表示是CCCT,CGAGTCAGCT的最小表示為AGCTCGAGTC.
輸入:
在輸入檔案的第一行 為序列數量。每一個測試用例都需要一行包含一個迴圈序列,這個序列被寫成一個任意的線性序列。由於迴圈序列是DNA串,只有四個符號:A,C,G,T。每一序列的長度為n(2<=n<=100)。
輸出:
每行為串的字典序最小的序列。下面的樣例為2個串的序列。
#include<iostream>
#include<cstring>
using namespace std;
#define max 105
int judge(int i,int ans,char *a);//指標是char型別的喲
int main()
{
int t;
scanf ("%d\n",&t);
char a[max];
memset(a,'\0',sizeof(a));
while(t--){
gets(a);
int n=strlen(a),ans=0;
for(int i=0;i<n;i++)
if(judge(i,ans,a)) ans=i; //只要當前下標的字典序小於之前的,就將它用 ans記錄下來,即不斷更新ans
for(int i=0;i<n;i++)
cout<<a[(i+ans)%n];//取模的意義在於迴圈陣列,實現環狀序列。
cout<<endl;
}
return 0;
}
int judge(int i,int ans,char *a) //看看從i開始的字典序小還是ans開始的字典序小,比較字典序是從第一個不同的字元開始比較
{
int n=strlen(a);
for(int j=0;j<n;j++)
if(a[(i+j)%n] != a[(ans+j)%n])
return a[(i+j)%n] < a[(ans+j)%n];//若下標i開始的字典序小,則返回1,否則返回0.
return 0; //如果下標i開始的字典序與下標ans開始的字典序完全相等,則返回0.
}