演算法競賽入門經典—例題3-6—環裝序列—UVa1584
阿新 • • 發佈:2018-12-20
題目描述
長度為n的換證串有n種表示法,分別為從某個位置開始順時針得到。例如圖:
有10種表示:CGAGTCAGCT,GAGTCAGCTC,AGTCAGCTCG等。在這些表示法中,字典序最小的成為“最小表示”。
輸入一個長度為n(n<=100)的環狀DNA串(只包含A,C,G,T)的一種表示法你的任務是輸出該環狀串的最小表示。例如,CTCC的最小表示是CCCT。CGAGTCAGCT的最小表示為AGCTCAGTC。
分析
本題出現了一個新概念,字典序。就是字串在字典中的順序。一般對於兩個字串,從第一個字元開始比較。當某一個的字元不同時,該位置字元較小的串,字典序較小(例如,abc比bcd小);如果其中一個字串已經沒有更多字元,但另一個字串還沒結束,則較短的字串的字典序較小(例如,hi比history小)。字典序的概念可以推廣到任意序列,例如,序列1,2,4,7,比1,2,5小。學會了字典序的概念之後,本題就不難解決了:就像“求n個元素中的最小值”一樣,用變數ans表示目前為止,字典序最小串在輸入串中的起始位置,然後不斷更新ans。
程式碼
#include<stdio.h>
#include<string.h>
#define maxn 100005
int ans[maxn];
int main()
{
int T,n;
memset(ans, 0,sizeof(ans));
for(int m=1;m<maxn;m++)
{
int x=m,y=m;
while(x>0)
{
y+=x%10;
x/=10;
}
if(ans[y]==0||m<ans[y]) ans[y]=m;
}
scanf("%d",&T);
while (T--)
{
scanf("%d",&n);
printf("%d\n",ans[n]);
}
return 0;
}
知識點
C 庫函式 - memset()
描述
C 庫函式 void *memset(void *str, int c, size_t n) 複製字元 c(一個無符號字元)到引數 str 所指向的字串的前 n 個字元。
宣告
void *memset(void *str, int c, size_t n)
引數
str -- 指向要填充的記憶體塊。 c -- 要被設定的值。該值以 int 形式傳遞,但是函式在填充記憶體塊時是使用該值的無符號字元形式。 n -- 要被設定為該值的位元組數。
返回值
該值返回一個指向儲存區 str 的指標。
總結
別人都是邊看題邊學演算法,我是邊看題邊學C嗎。。。。。。。。