1. 程式人生 > 其它 >例題3-6 環狀序列ACM程式碼+註釋

例題3-6 環狀序列ACM程式碼+註釋

技術標籤:演算法acm競賽icpcc++c語言

例題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. }