算法演练(一)

算法练习题(一)

1.题型:数组与字符串

例一:生成元问题

题目:如果x+x的各个数字之和得到y,就是说x是y的生成元。给出n(1<=n<=100000),求最小生成元。无解输出0.例如,n=216,121,2005时的解分别是198,0,1979。

解题思路:枚举100000内的所有正整数m,标记“m加上m的各个数字之和得到的数有一个生成元是m”,最后查表即可。(打表法)

代码:

#include<stdio.h>
#include<string.h>
#define maxn 100005
int ans[maxn];

int main() {
int T, n;
memset(ans, 0, sizeof(ans));
int m;
for (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;  // 疑问:ans[y]的值来源于m,m为累加数,m<ans[y]的情况似乎并不存在。
}

scanf("%d", &T);
while (T--) {
	scanf("%d", &n);
	printf("%d
", ans[n]);
}
return 0;
}

#注:本题目及代码源于刘汝佳 著《算法竞赛 入门经典》第二版。

例二:环状序列问题

题目:长度为n的环状串有n种表示方法,分别为从某个位置开始顺时针得到,在这些排列中字典顺序最小的称“最小表示”。如CTCC的最小表示为CCCT,CGAGTCAGCT的最小表示为AGCTCGAGTC。

解题思路:对于两个字符串,从第一的字符开始比较,当某一个位置的字符不同时,该位置字符较小的串,字典序小。如果一个字符串没有更多的字符,但另一个字符串还没结束,则较短的字符串的字典序较小。其实就是定义两个int变量并分别记录数组的下标,一个用于循环,一个用于记录当前开始最小的字符串的下标。

代码:

#include<stdio.h>
#include<string.h>
#define maxn 105

// 环状串s的表示法p是否比表示法q的字典序小 
int less (const char* s, int p, int q) {
    int n = strlen(s);
    int i;
    for (i = 0; i < n; i++)
	    if (s[(p+i) % n] != s[(q+i) % n])
	        return s[(p+i) % n] < s[(q+i) % n];
    return 0;  // 相等 
} 

int main() {
    int T;
    char s[maxn];
    scanf("%d", &T);   // 输入要检测序列数
    while (T--) {
	    scanf("%s", s);
	    int ans = 0;
	    int n = strlen(s);
	    int i;
	    for (i = 1; i < n; i++)
	    	if (less(s, i, ans))  ans = i;
	    for (i = 0; i < n; i++)
		    putchar(s[(i+ans) % n]);
    	putchar('
');
    }
    return 0;
}

#注:本题目及代码源于刘汝佳 著《算法竞赛 入门经典》第二版。

从现在开始每周写博客,立此为据!!! (2017/03/04)

附:诗

偶然

----徐志摩

我是天空里的一片云,
偶尔投影在你的波心--
你不必讶异,
更无须欢喜--
在转瞬间消灭了踪影。

你我相逢在黑夜的海上,
你有你的,我有我的,方向;
你记得也好,
最好你忘掉,
在这交会时互放的光亮!

以上

原文地址:https://www.cnblogs.com/mxwbq/p/6501991.html