Circular Sequence UVa1584
描述:
长度为n的环状串有n种表示方法,分别为从某个位置开始顺时针得到,在这些排列中字典顺序最小的称“最小表示”。
如CTCC的最小表示为CCCT,CGAGTCAGCT的最小表示为AGCTCGAGTC。
代码:
1 #include<stdio.h> 2 #include<string.h> 3 #define maxn 110 4 5 6 char a[maxn]; //the array entered by users. 7 char b[maxn]; //the array used to save the temp array. 8 9 //chang ABCD into BCDA...... 10 void sort_array(char temp[], int length) 11 { 12 char fir = temp[0]; 13 for (int i = 1; i<length; i++) 14 { 15 temp[i-1] = temp[i]; 16 } 17 temp[i-1] = fir; 18 } 19 20 int main() 21 { 22 scanf("%s",a); 23 strcpy(b,a); 24 int length = strlen(a); 25 for (int i = 0; i<length; i++) 26 { 27 sort_array(b, length); 28 if(strcmp(b,a) == -1) strcpy(a,b); 29 } 30 printf("%s\n",a); 31 return 0; 32 }
思路:
- 将环状解开变成一个一位数组,由于是环状的,所以不能随便移动元素的位置,可以选择所有元素向前推一个,然后将第一个元素放在最后,通过不断的重复和比对最终得到一个最佳的答案。
注意点:
- strcmp中如果第一个字符串大于第二个字符串,那么返回值为1;如果第一个字符串等于第二个字符串,返回值为0;如果第一个字符串小于第二个字符串返回值为-1。
补充:
- 算法书中的方法用的是取mod的方法,挺有趣的,可以看看。
- 在这个算法中,没有动这个环,而是选择了使用一个类似于指针的东西(ans),标注读取环的开始位置,并通过循环来找到最好的位置。
代码如下:
1 #include<stdio.h> 2 #include<string.h> 3 #define maxn 110 4 5 6 // judging the letter, which is not the same, after the index(ans) 7 // smaller : ans = i; 8 // bigger : ans = ans;(do not change) 9 10 //using index%n just like a ring that connects the head and tail. 11 int less(char *s, int p, int q) 12 { 13 int length = strlen(s); 14 for (int i = 0; i < length; i++) 15 if(s[(p+i)%length] != s[(q+i)%length]) 16 return (s[(p+i)%length] < s[(q+i)%length]); 17 return 0; 18 } 19 20 21 22 int main() 23 { 24 char s[maxn]; 25 scanf("%s",s); 26 int ans = 0; 27 int n = strlen(s); 28 for(int i = 1; i < n; i++) 29 { 30 if(less(s,i,ans)) ans = i; 31 } 32 for(i = 0; i < n; i++) 33 { 34 putchar(s[(i+ans)%n]); 35 } 36 putchar('\n'); 37 return 0; 38 }
Do not let your ego get in you way!