编程练习 15.12.07~15.12.14

来源:互联网 发布:苹果医药软件 编辑:程序博客网 时间:2024/06/06 00:55

    • 破译密文
      • 读题
      • my answer
      • the standard answer
      • 反馈
    • Bucket sort
      • 读题
      • my answer
      • the standard answer
      • 反馈
    • Pascal triangle
      • 读题
      • my answer
      • the standard answer
      • 反馈
    • 合并字符串for hw
      • 读题
      • my answer
      • the standard answer
      • 反馈
    • Ant
      • 读题
      • my answer
      • the standard answer
      • 反馈
    • eggsfor hw
      • 读题
      • my answer
      • the standard answer
      • 反馈
    • Is the order a rabbitfor hw
      • 读题
      • my answer
      • the standard answer
      • 反馈


破译密文

题目大意:Mo and Larry have devised a way of encrypting messages. They first decide secretly on the number of columns and write the message (letters only) down the columns, padding with extra random letters so as to make a rectangular array of letters. For example, if the message is “There’s no place like home on a snowy night” and there are five columns, Mo would write down t o i o y h p k n n e l e a i r a h s g e c o n h s e m o t n l e w x Note that Mo includes only letters and writes them all in lower case. In this example, Mo used the character `x’ to pad the message out to make a rectangle, although he could have used any letter. Mo then sends the message to Larry by writing the letters in each row, alternating left-to-right and right-to-left. So, the above would be encrypted as toioynnkpheleaigshareconhtomesnlewx Your job is to recover for Larry the original message (along with any extra padding letters) from the encrypted one.

输入:Input will consist of two lines. The first line will contain an integer in the range 2 . ..20 indicating the number of columns used. The next line is a string of up to 200 lower case letters.

输出:giving the original plaintext message, with no spaces and a new line in the end.

样例:

输入:
3
ttyohhieneesiaabss

输出:
thisistheeasyoneab

Hint:

数组操作。

scanf(“%d”, &num);
char tempChar = getchar();
char str[201];
gets(str);
int len = strlen(str);

读题

这道题目做过,只不过当时是,有很多案例,这次的input只有一个案例

my answer

#include <stdio.h>#include <string.h>  // we have done it beforint main() {    char a[30][200], arr[300];    int n, col, i, j;    int k;        scanf("%d", &col);        scanf("%s", &arr);        n = strlen(arr);        k = 0;        for (i = 0; i < n / col; i++) {            for (j = 0; j < col; j++) {                if (i % 2 == 1) {                    a[i][col-j-1] = arr[k++];                } else {                    a[i][j] = arr[k++];                }            }        }        for (i = 0; i < col; i++) {            for (j = 0; j < n/col; j++) {                printf("%c", a[j][i]);            }        }        printf("\n");    return 0;}

the standard answer

/* * this is the direct but stupid way. you can improve it by yourself by using one array. */#include<stdio.h>#include<string.h>char tmp[101][21];char temp[101][21];. int main() {    int num, i, j;    // for input.    scanf("%d", &num);    char tempChar = getchar();    char str[201];    gets(str);    int len = strlen(str);    int row = len/num;    for (i = 0; i < len; i++) {        tmp[i/num][i%num] = str[i];    }    // for processing.    for (i = 0; i < row; i++) {        for (j = 0; j < num; j++) {            if (i%2 == 1) temp[i][j] = tmp[i][num - j - 1];            else temp[i][j] = tmp[i][j];        }    }    // for output.    for (i = 0; i < num; i++) {        for (j = 0; j < row; j++) {            printf("%c", temp[j][i]);        }    }    printf("\n");    return 0;}

反馈

Bucket sort

Input a couple of numbers (0~100) and end of EOF.

If number > 20, it shuold be mapped to [0, 20],whitch is mean ‘number %= 21’

Output all these numbers by ascending oder.

Output format: behind every number, there is a space ’ ‘. And no ‘\n’

For example:

[Input]

1 2 22 3 3 44 5 55 6 66 7 20 21 23 100 101

[Output]

0 1 1 2 2 2 3 3 3 5 6 7 13 16 17 20

Hint:

输入数据范围较集中,建议用桶排序。

windows下出入EOF:换到新的一行,输入ctrl+Z

linux下输入EOF:换到新的一行,输入ctrl+D

出现题目有误,可以发邮件给TA。如果无法及时更改,请大家在评论区相互提醒一下。

由于用到数组,批改的时候需要检查内存,可能会有些慢。

读题

桶排序
桶排序 (Bucket sort)或所谓的箱排序,是一个排序算法,工作的原理是将数组分到有限数量的桶子里。每个桶子再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序)。桶排序是鸽巢排序的一种归纳结果。当要被排序的数组内的数值是均匀分配的时候,桶排序使用线性时间(Θ(n))。但桶排序并不是 比较排序,他不受到 O(n log n) 下限的影响。

由于我们要排的是0~20,都是整数,所以可以直接用数组下标来表示不同的桶代表的值..每个数组里的数a[i]的值为.要排序的数中,大小为i的数的.个数

my answer

#include<stdio.h>int main() {    int temp, i;    int bucket[21] = {0};    while (scanf("%d", &temp) != EOF) {        temp = temp % 21;        bucket[temp]++;    }    for (i = 0; i <= 20; i++)    while (bucket[i]--)    printf("%d ", i);    return 0;}

the standard answer

#include<stdio.h>int main() {    int a[21] = {0};    int num, i;    while (scanf("%d", &num) != EOF) {        if (num > 20)            num %= 21;        a[num]++;    }    for (i = 0; i < 21; ++i) {        if (a[i] == 0)            continue;        while (a[i]--)            printf("%d ", i);    }    return 0;}

反馈

Pascal triangle

By using two-dimensional array, write C program to display a table that represents a Pascal triangle of any size. In Pascal triangle, the first and the second rows are set to 1. Each element of the triangle (from the third row downward) is the sum of the element directly above it and the element to the left of the element directly above it. See the example Pascal triangle(size=5) below:

1
1 1
1 2 1
1 3 3 1
1 4 6 4 1

// main.c#include <stdio.h>#include "triangle.h"void printPascalTr(int size);int main() {    int size;    printf("Enter Pascal triangle size:");    scanf("%d", &size);    printPascalTr(size);    getchar();    return 0;}

读题

每行第一个和最后一个数是1;中间的数等于它头顶和它头顶左边的数的和

my answer

#include<stdio.h>void printPascalTr(int size) {    int i, j;    int  a[size+1][size+1];    a[1][1] = 1; a[2][1] = 1; a[2][2] = 1;    if (1 == size) {        printf("%d\t\n", 1);    } else {    printf("%d\t\n%d\t%d\t\n", 1, 1, 1);    for (i = 3; i <= size; i++) {        for (j = 1; j <= i; j++) {            if (j == 1 || j == i) {                a[i][j] = 1;                printf("%d\t", a[i][j]);            } else {                a[i][j] = a[i - 1][j] + a[i - 1][j - 1];                printf("%d\t", a[i][j]);            }        }        printf("\n");    }    }    return;}

the standard answer

#ifndef triangle_h#define triangle_h#include <stdio.h>void printPascalTr(int size) {    int PascalTr[size][size];    int row, col;    // assign zero to every array element    for (row = 0; row < size; row++)        for (col = 0; col < size; col++)            PascalTr[row][col] = 0;    // first and second rows are set to 1s    PascalTr[0][0] = 1;    PascalTr[1][0] = 1;    PascalTr[1][1] = 1;    for (row = 2; row < size; row++) {        PascalTr[row][0] = 1;        for (col = 1; col <= row; col++) {            PascalTr[row][col] = PascalTr[row - 1][col - 1]            + PascalTr[row - 1][col];        }    }    // display the Pascal Triangle    for (row = 0; row < size; row++) {        for (col = 0; col <= row; col++) {            printf("%d\t", PascalTr[row][col]);        }        printf("\n");    }}#endif /* triangle_h */

反馈

合并字符串(for hw)

合并两个字符串,每个字符串长度不小于1不超过50,

主函数已经给出,在join.h头文件中完成join函数,函数原型如下:

char* join(char* a, int alength, char* b, int blength)

需要在join函数中动态申请内存,长度为a和b长度之和加1(因为字符串结尾有‘\0’); 函数返回值即所动态申请内存的首地址。

输入:两个字符串,每个一行

输出:合并后的字符串及所申请内存的实际大小,字符串一行,实际大小一行

Sample:

input:

1234

567890

output:

1234567890

24

Hint:
使用malloc函数进行动态内存申请,申请到的实际内存大小与操作系统相关,大部分情况下不等于所申请的具体数值。

// main.c#include<stdio.h>#include<stdlib.h>#include<string.h>#include<malloc.h>#include"join.h"#define MAX 51int main() {    char a[MAX];    char b[MAX];    char* c = NULL;    scanf("%s", a);    scanf("%s", b);    c = join(a, strlen(a), b, strlen(b));    printf("%s\n", c);    printf("%d\n", malloc_usable_size(c));    free(c);    return 0;}

读题

my answer

#ifndef __join_h__#define __join_h__#include<stdio.h>#include<stdlib.h>char* join(char* a, int alength, char* b, int blength) {    char * p;    int i;    char ch = 'A';    p = malloc(sizeof(ch) * (alength + blength + 1));    for (i = 0; i < alength; i++)        * (p + i) = * (a + i);    for (i = 0; i <= blength; i++)        * (p + i + alength) = * (b + i);    return p;}#endif

the standard answer

#ifndef __JOINS__2.#define __JOINS__3.#include<stdio.h>4.#include<stdlib.h>5.#include<string.h>6.#include<malloc.h>7.char* join(char* a, int alength, char* b, int blength) {8.    char* c = malloc(sizeof(a[0]) * (alength + blength + 1));9.    memcpy(c, a, sizeof(a[0]) * alength);10.    memcpy(c + alength, b, sizeof(b[0]) * blength);11.    c[alength + blength] = '\0';12.    return c;13.}14.#endif

反馈

Ant

一根长度为L厘米的木棒上有N只蚂蚁,每只蚂蚁要么向左走,要么向右走,速度为1厘米/秒。当两只蚂蚁相撞时,他们会同时掉头(掉头时间不计)给出每只蚂蚁距离木棒左端的距离,问多少秒后,刚好所有蚂蚁都从木棒上掉下来。

N 和 L均不超过1000

输入第一行两个整数,分别是N和L

接下来N行,每行先是一个字符,L或R,代表向左还是向右,然后是一个整数x,代表这个蚂蚁距离木棒左端的距离。

样例输入:
4 10
R 1
R 5
L 3
R 9
样例输出:

9
Hint:
假设你在远处观察两只蚂蚁相向而行,他们相撞后掉头,和直接穿过有什么区别?

读题

这个题目- -看完提示之后就发现其实就是个字符处理和找最大值的问题.

my answer

#include<stdio.h>int main() {    int i, n, len, templen, max = 0;    char tempdir;    scanf("%d%d", &n, &len);    for (i = 0; i < n; i++) {        scanf("%c%d", &tempdir, &templen);        if (tempdir == 'R')            templen = len - templen;        if (templen > max)            max = templen;    }    printf("%d\n", max);    return 0;}

the standard answer

#include<stdio.h>2.int main() {3.    int n, l, x, sum = 0, i;4.    char s[11];5.    scanf("%d%d", &n, &l);6.    for (i = 1; i <= n; i++) {7.        scanf("%s%d", s, &x);8.        if (s[0] == 'R') x = l - x;9.        if (x > sum) sum = x;10.    }11.    printf("%d\n", sum);12.    return 0;13.}

反馈

eggs(for hw)

Erin买了不少鸡蛋,她发现一天吃不完这么多,于是决定把n个同样的鸡蛋放在m个同样的篮子里,允许有的篮子空着不放,请问共有多少种不同的放法呢?

注意:2,1,1和1,2,1 是同一种分法。

Input
第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数m和n,以空格分开。1<=m,n<=10。

Output
对输入的每组数据m和n,用一行输出相应的结果。
例如:
Input:
4
3 8
4 7
2 4
4 2

Output:
10
11
3
2

(注意结尾有换行)

Hint:
尝试利用递归去分析解题,即不同情况下应该怎么返回。

可以尝试用树状图(然而我觉得用处不大)。

注意篮子可以空着不放,请先想明白示例中最后两个例子再做题。

读题

我的思路是这样的把鸡蛋逐个篮子地放
只要保持降序,就能保证不重复.
但是这样的话就复杂化了.

my answer

#include<stdio.h>static int ans = 0;void eggs(int , int, int);int main() {    extern int ans;    int n, egg, basket;    scanf("%d", &n);    while (n--) {        ans = 0;        scanf("%d%d", &basket, &egg);        eggs(basket, egg, egg);        printf("%d\n", ans);    }    return 0;}void eggs(int basket, int left, int lastone) {    extern int ans;    int i;    for (i = lastone > left ? left : lastone; i >= 0; i--) {        if (basket == 1) {            ans = 1;            return;        }        if (left == 0) {            ans++;            continue;        } else if (basket == 2) {            if (i >= left - i) {                ans++;                continue;            } else {                continue;            }        } else {            eggs(basket - 1, left - i, i);        }    }    return;}

the standard answer

#include<stdio.h>int egg(int baskets, int eggs);int main() {    int t;    int baskets, eggs;    int result = 0;    scanf("%d", &t);    while (t--) {        scanf("%d %d", &baskets, &eggs);        result = egg(baskets , eggs);        printf("%d\n", result);    }    return 0;}int egg(int baskets, int eggs) {    if (baskets == 1 || eggs == 0)        return 1;    if (eggs < 0)        return 0;    return egg(baskets - 1, eggs) + egg(baskets, eggs - baskets);}

答案这种解法的意思是:
比如当前有3个篮子8个鸡蛋,所有的就是
第三个篮子的空的 和 第三个篮子一定有鸡蛋 两种情况,
一 即所有蛋放在前两个篮子里 问题变成了
往(3 - 1=) 2个篮子里放8个鸡蛋.
二因为保持降序,所以三个篮子都必须至少一个鸡蛋 问题就变成了 往三个篮子里放(8 - 3 =) 5个鸡蛋.

推广到basket个篮子,eggs个鸡蛋的情况
egg(int baskets, int eggs)
= egg(baskets - 1, eggs) + egg(baskets, eggs - baskets)

什么时候终止?
因为递归到最后一个篮子,是数量最多的篮子,所以只要到最后一个篮子就可以+1;如果鸡蛋数量为0,则说明上一次已经分好了,所以return1;如果鸡蛋数量小于0,说明上一步不能实现,也就是这个分法不可行,所以return 0;

尝试写一个例子可以帮助理解.

反馈

Is the order a rabbit(for hw)

You must know the famous problem which the answer is Fibonacci Number: “A newly born pair of rabbits, one male, one female, are put in a field; rabbits are able to mate at the age of one month so that at the end of its second month a female can produce another pair of rabbits; rabbits never die and a mating pair always produces one new pair (one male, one female) every month from the second month on. How many pairs will there be after n months?”

Chino is interested in such problems. She thinks that the rabbits in this problem have 2 stages in their life: the first stage lasts one month that rabbits don’t produce rabbits in this stage; and the second stage lasts forever, each pair of rabbits produces one pair of rabbits every month in the second stage. Now she is considering a more complicated situation: the rabbits have m stages. In the first stage, they don’t produce rabbits. In the i-th stage, each pair of rabbits produces one pair of rabbits every i-1 month(s). The i-th stage lasts Ki month(s), and the rabbits die at the end of the last month of the m-th stage. The question is the same: how many pairs of rabbits will there be after n months?

As for detail, rabbits produce rabbits at the beginning of a month (different from the classic problem in the first paragraph), die at the end of a month, and we count the rabbits at the middle of a month. Also, the rabbits will produce rabbits at the first month of each stage (except the first stage)

Input Format

The input contains 2 lines:

There are 2 integers in the first line: m n, 0 < m < 6, 0 <= n <= 1e9

There are m integers in the second line: K1 K2 … Km, 0 < Ki <= 40

Output Format

Only one integer: the answer mod 10007 (since the answer may be very large).

And don’t forget the ‘\n’.

Sample Input 1

4 5

1 2 4 8

Sample Output 1

29

Sample Input 2

4 1000000000

1 2 4 8

Sample Output 2

8435

Sample Input 3

3 7

1 2 4

Sample Output 3

103
Hint:
1) (a+b)%P = ((a%P)+(b%P))%P; (ab)%P = ((a%P)(b%P))%P

2) 直接推递推公式也会有困难,建议计算出转换矩阵,使得Ai+1=TAi

3) 在以上基础上推Tn计算TnA0,推Tn可用快速幂

读题

my answer

the standard answer

反馈

0 0
原创粉丝点击