校招季——编程题目(6-7)

来源:互联网 发布:好用的补水乳液 知乎 编辑:程序博客网 时间:2024/05/16 18:02

2013/08/15,第四天

6.      反转单词(题目007

题目:

字符串中的每个单词内的字母顺序倒转,其它字符不变

解答:

void ReverseString(char *s){    int n = strlen(s), start = -1, i;    for (i = 0; i <= n; ++i)        if (!isalpha(s[i]))        {            ReverseWord(&s[start+1], i–start-1);            start = i;        }}void ReverseWord(char *s, int n){    if (n < 2)        return;    int i;    for (i = 0; i < n/2; ++i)        Swap(&s[i], &s[n-i-1]);}

7.      放苹果/和的数量(题目025、题目053

题目:

题目025:把m个苹果放在n个盘子里,允许有空的盘子或多个苹果的盘子,共有多少种不同的分法?

题目053输入mn,从[1,n]中取出若干个不相同的数,使其和等于m。打印出各种可能。

解答:

f(m,n)为题目025的解,可知以下几个性质:

1.     n>mf(m,n)=f(m,m)

2.     f(0,n)=f(m,1)=1

3.     重点来了,f(m,n)=f(m,n-1)+f(m-n,n)

对第3条的解释:f(m,n)可认为是n个盘子里放m个苹果,如果至少有一个盘子是空的,则此情况等价于n-1个盘子里放m个苹果f(m,n-1),即将那个空盘子排除掉;如果所有盘子都至少有一个苹果,则此情况等价于每个盘子放一个苹果后n个盘子里放m-n个苹果f(m-n,n)

题目053与题目025类似,区别在于:

1.     终止条件为f(0,n)=f(m,0)=0

2.     m<n时可直接输出一种结果,但还需要继续寻找其它可能。

3.     迭代式为:f(m,n)=f(m-n,n-1)+f(m,n-1)

对第3条的解释:我们从后向前寻找可能的解,如果n这个数是解的一部分,则此情况等价于f(m-n,n-1),如果n不是解的一部分,则等价于f(m,n-1)

025方法1

直接自顶向下递归进行,代码简洁,但包含大量的重复子问题的计算,速度较慢。

double Func_1(int M, int N){if (M < N)N = M;if (M==0 || N==1)return 1.0;elsereturn Func_1(M - N, N) + Func_1(M, N - 1);}

025方法2

将上面的方法改成动态规划,迭代进行。

double Func_2(int M, int N){if (N > M)N = M;double **data = malloc2d(M + 1, N + 1, sizeof(double));int i, j;for (j = 0; j <= N; ++j)data[0][j] = 1;for (i = 0; i <= M; ++i)data[i][1] = 1;for (i = 1; i <= M; ++i)for (j = 2; j<=N; ++j)if (j > i)data[i][j] = data[i][i];elsedata[i][j] = data[i][j-1] + data[i-j][j];double ret = data[M][N];free2d(data, M + 1);return ret;}

025方法3

将方法1改为备忘录形式,避免重复计算。

double Func_3(int M, int N){if(N>M)N=M;double **data = (double **)calloc2d(M+1, N+1, sizeof(double));double ret = RealFunc_3(M, N, data);free2d(data,M);return ret;}double RealFunc_3(int M, int N, double **data){if (M < N)N = M;if (M == 0 || N == 1)return 1.0;if (data[M][N] > 0)return data[M][N];elsereturn data[M][N] = RealFunc_3(M-N, N, data) + RealFunc_3(M, N-1, data);}

053:

int g_sequence[10000] = {0};void PrintSequence(int lenth){int i;for (i = 0; i < lenth - 1; ++i)printf("%d,", g_sequence[i]);printf("%d\n", g_sequence[i]);}void Find(int m, int n, int pos){if (m < 1 || n < 1)return;if (m < n)n = m;if (m <= n) {g_sequence[pos] = m;PrintSequence(pos + 1);}g_sequence[pos] = n;Find(m - n, n - 1, pos + 1);Find(m, n - 1, pos);}

原创粉丝点击