1. 程式人生 > >演算法競賽入門經典—例題3-6—環裝序列—UVa1584

演算法競賽入門經典—例題3-6—環裝序列—UVa1584

題目描述

長度為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嗎。。。。。。。。