编程练习 15.11.30~15.12.06

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

    • simple calculator for lab
      • 读题
      • my answer
      • the standard answer
      • 反馈
    • Recursion for binary
      • 读题
      • my answer
      • the standard answer
      • 反馈
    • 函数与递归练习
      • 读题
      • my answer
      • the standard answer
      • 反馈
    • 挑战高楼for hw
      • 读题
      • my answer
      • the standard answer
      • 反馈
    • JumpJump
      • 读题
      • my answer
      • the standard answer
      • 反馈
    • 完全二叉树深度优先搜索for hw
      • 读题
      • my answer
      • the standard answer
      • 反馈
    • 拯救大兵雷诺
      • 读题
      • my answer
      • my answer 2
      • the standard answer
      • 反馈


simple calculator (for lab)

Write C code that will display the calculator menu.

The program will prompt the user to choose the operation choice (from 1 to 5). Then it asks the user to input two integer vales for the calculation. See the sample below.
MENU
1. Add
2. Subtract
3. Multiply
4. Divide
5. Modulus
Enter your choice: 1
Enter your two numbers: 12 15
Result: 27

your task: to complete the function called by main in cal.h(在cal.h文件中实现main中调用的函数)

#include <stdio.h>#include <stdlib.h>#include "cal.h"void displaymenu() {    printf("================================\n");    printf("      MENU                  \n");    printf("================================\n");    printf("     1.Add\n");    printf("     2.Subtract \n");    printf("     3.Multiply \n");    printf("     4.Divide \n");    printf("     5.Modulus \n");}int main(int argc, char *argv[]) {    displaymenu();    int yourchoice;    int a;    int b;    printf("Enter your choice(1-5):");    scanf("%d:", &yourchoice);    printf("Enter your two integer numbers:");    scanf("%d %d", &a, &b);    printf("\n");    switch (yourchoice) {        case 1:            printf("Result:%d\n", Add(a, b));            break;        case 2:            printf("Result:%d\n", Substract(a, b));            break;        case 3:            printf("Result:%d\n", Multiply(a, b));            break;        case 4:            printf("Result:%.2f\n", Divide(a, b));            break;        case 5:            printf("Result:%d\n", Modulus(a, b));            break;        default:            printf("Invalid\n");        }    return 0;}

读题

这个题要求我们写头文件,写自定义函数,实现加减乘除求模.

my answer

int Add(int a, int b);int Substract(int a, int b);int Multiply(int a, int b);float Divide(float a, float b);int Modulus(int a, int b);int Add(int a, int b) {    return a + b;}int Substract(int a, int b) {    return a - b;}int Multiply(int a, int b) {    return a * b;}float Divide(float a, float b) {    return a / b;}int Modulus(int a, int b) {    return a % b;}

the standard answer

#ifndef cal_h#define cal_hint Add(int a, int b) {    return(a + b);}int Substract(int a, int b) {    return(a - b);}int Multiply(int a, int b) {    return(a * b);}float Divide(float a, float b) {    return(a / b);}int Modulus(int a, int b) {    return(a % b);}#endif /* cal_h */

反馈

写头文件要加这部分.

#ifndef cal_h#define cal_h#endif

// 上述宏定义是为了防止encrypt.h被重复声明// 如果已经引用了这个.h文件一次,cal_h 就已经定义过了// 再次引用就会跳过这块内容,直到#ednif下方

不需要函数声明(?)

(除法要用浮点数)

Recursion for binary

Give a decimal number n(1~200),please use recursion function to convert it to binary number.

output format: no ‘\n’
For example

[Input]

2

[Output]

10

[Input]

10

[Output]
1010

Hint:

tips:可参考下面的递归函数实现方式,也可以用自己想的方式实现。

void binary(int dec);

1.终止条件:传入的dec为0

2.继续调用binary函数,传入除以2的dec

3.输出当前(除以2前)的dec模2的余数

读题

my answer

#include<stdio.h>int main() {    int n, i;    int a[9] = {0};    scanf("%d", &n);    int mod = 1;    int len = 0;    for (i = 0; n != 0; i++) {        mod = n % 2;        n /= 2;        a[i] = mod;        len++;    }    for (i = len - 1; i >= 0; i--)    printf("%d", a[i]);    return  0;}

the standard answer

#include <stdio.h>void binary(int dec);int main() {    int dec;    scanf("%d", &dec);    binary(dec);    return 0;}void binary(int dec) {    if (dec == 0)        return;    binary(dec / 2);    printf("%d", dec % 2);}

反馈

用递归实现从右到左打印..

函数与递归练习

请实现下面两个函数,分别完成对两个数求最大公约数,和求一个数阶乘的求解。

要求:两个函数都需要递归实现求解,否则本题按0分处理。主函数已给出如下:

#include<stdio.h>// function declares here, first is Greatest common divisor, next is factorial.int gcd(int m, int n);int fac(int p);int main(void) {  int a, b, c;  scanf("%d%d%d", &a, &b, &c);  printf("%d %d\n", gcd(a, b), fac(c));}// next is function's defintion.

你只需要利用递归实现这两个函数。

ps: 强烈建议大家课后可以看看期中测试题目的Maxmal Discount那道题的答案。(学习递归函数的运用,合并排序,指针,内存管理)

因为所写的内容比较少,避免误判为抄袭,请各位为你的函数多写注释。

Hint:
最大公约数:辗转相除法。

阶乘:按定义求解即可

读题

my answer

#include<stdio.h>// function declares here, first is Greatest common divisor, next is factorial.int gcd(int m, int n);int fac(int p);int main(void) {  int a, b, c;  scanf("%d%d%d", &a, &b, &c);  printf("%d %d\n", gcd(a, b), fac(c));}  // next is function's defintion.int gcd(int m, int n) {    int temp;    if (m < n) {        temp = m;        m = n;        n = temp;  // sort    }    if (m % n == 0) {  // end sign        return n;    } else {        return gcd(n, m%n);    }}int fac(int p) {    int result;    result = p;    if (p == 1) {  // end sign        return result;    } else {        p--;        result *= fac(p);    }}

the standard answer

// from younglee#include<stdio.h>// function declares here, first is Greatest common divisor, next is factorial.int gcd(int m, int n);int fac(int p);int main(void) {    int a, b, c;    scanf("%d%d%d", &a, &b, &c);    printf("%d %d\n", gcd(a, b), fac(c));}// next is function's defintion.int gcd(int m, int n) {    if (n == 0) return m;    return gcd(n, m%n);}int fac(int p) {    if (p == 1) return 1;    return p*fac(p - 1);}

反馈

挑战高楼(for hw)

Jeremy想要参加广州塔的垂直马拉松活动,然而Jeremy发现在爬楼梯的过程中有不同的方式:他可以一次走1级台阶,也可以一次走2级台阶。

现在Jeremy准备在学校的楼梯进行练习准备,请问你可以算出他在m次爬n级台阶的时候,有多少种不同的方式吗?(利用函数进行计算,例如第n层的结果取决于第n-1和n-2层的结果)

输入输出格式如下:

input:

m
n1
n2
n3

nm (一共m个n值)

( 0< m < 20, 0 < n < 44)

output:
result1
result2
result3

resultm

(一共m个result,结尾有换行)

例如:
intput:
3
3
10
30
output:
3
89
1346269

Hint:
由于数据范围比较大,建议设置变量类型的时候用long

读题

my answer

#include<stdio.h>long ways(int n);int main() {    int m, n, i;    scanf("%d", &m);    for (i = 0; i < m; i++) {        scanf("%d", &n);        printf("%ld\n", ways(n));    }    return 0;}long ways(int n) {    if (n == 1) {        return 1;    } else if (n == 2) {        return 2;    } else {        int i;        int w1 = 1, w2 = 2, x = 0;        for (i = 3; i <= n; i++) {            x = w1 + w2;            w1 = w2;            w2 = x;        }        return x;    }}

the standard answer

#include <stdio.h>long num(long n) {    if (n == 1 || n == 2)        return n;    long step1 = 1, step2 = 2, result = 0;    long temp = 3;    for (temp = 3; temp <= n; temp++) {        result = step1 + step2;        step1 = step2;        step2 = result;    }    return result;}int main() {    long m, n;    scanf("%ld", &m);    while (m--) {        scanf("%ld", &n);        printf("%ld\n", num(n));    }    return 0;}

反馈

JumpJump

Description:
给出一个数组,长度为n,编号为0~(n-1),接下来n行,第i行描述关于第i个位置的信息。每行先是一个数k表示从位置i-1可以跳到其他的k个位置去,之后是k个数,表示i-1号点可以跳到的位置,这些位置一定在i-1号位置之后,且从小到大排列。

现在有一个小朋友,从0号位置出发,每次往他可以跳的位置跳过去,且从编号小的开始跳。如果遇到一个位置不能继续跳下去则返回之前的位置。

输出一路上途径的所有点。

例如,n= 5 n行数据如下

1 1

2 2 3

0

1 4

0

小朋友从0出发,可以跳到1去,然后从1可以跳到2和3,选择小的所以跳到了2,从2没有位置可以跳,所以返回1,再从1跳往3, 3可以继续跳到4,到4后不能继续跳所以返回3,这时3也没有位置可以跳,继续返回1, 再返回0

所以要输出的就是0 1 2 1 3 4 3 1 0

为方便输出,每个数字,包括这一行最后一个数字,后面都跟一个空格。输出结尾要有换行

n不超过100,每个k都不超过5

Hint:
使用递归。

函数中的参数只需要记录当前在哪个点,然后枚举这个点可以跳过去的点,然后调用跳过去的点的函数。

跳过的位置不重复,是指本次从当前点往后跳时,跳过的不重复,比如1可以跳到5,6 2可以跳到6,那么如果1跳到5,返回到1,那么就不能再跳5,但是如果从1跳到6然后返回,下一次还是可以从2跳到6

这句话有点多余,题意直接理解为,每到一个点,就把这个点可以跳过去的点挨个跳一遍就行了。

读题

my answer

#include<stdio.h>void jump(int x, int len[], int a[][5]);int main() {    int i, j, n;    int a[100][5];    int len[100];    scanf("%d", &n);    for (i = 0; i < n; i++) {        scanf("%d", &len[i]);        for (j = 0; j < len[i]; j++) {            scanf("%d", &a[i][j]);        }    }    jump(0, len, a);    printf("\n");    return 0;}void jump(int x, int len[], int a[][5]) {    int i;    printf("%d ", x);        for (i = 0; i < len[x]; i++) {            jump(a[x][i], len, a);            printf("%d ", x);        }    return;}

the standard answer

#include<stdio.h>int a[110][10];void jump(int x) {    int i;    printf("%d ", x);    for (i = 1; i <= a[x][0]; i++) {        jump(a[x][i]);        printf("%d ", x);    }}int main() {    int n, i, j;    scanf("%d", &n);    for (i = 0; i < n; i++) {        scanf("%d", &a[i][0]);        for (j = 1; j <= a[i][0]; j++)            scanf("%d", &a[i][j]);    }    jump(0);    printf("\n");    return 0;}

反馈

直接用a[i][0]储存数组长度数据,不用再开len[]

完全二叉树深度优先搜索(for hw)

使用一个长度为N的数组,1<=N<=50,存储一棵完全二叉树。(二叉树中每个节点最多有两个子树称为左子树和右子树。完全二叉树是除最后一层外,每一层上的节点数均达到最大值;在最后一层上只缺少右边的若干节点。在数组中,如果以下标1为起始位置,那么每个节点的左儿子是其自己下标乘以2的节点,右儿子是自己下标乘以2加1的节点,即arr[i*2]和arr[i*2+1]是arr[i]的左右儿子。)然后使用左子树优先的深度优先搜索方法搜索一棵完全二叉树中的一个值为X的节点,最终输出其深度优先搜索的过程,如果一棵树中存在值相同的节点,以第一个被搜索到的为准然后结束。

本题目已给出main函数,需要以递归方式在头文件DFS.h中实现DFS函数,函数没有返回值,整个搜索过程的输出均在DFS函数中实现,函数有4个参数分别是:1、数组arr,2、数组长度N,3、下标位置pos,4、要被搜索的数字X。

输入:3行输入;第1行输入为长度N;第二行输入N个数字以空格间隔;第三行输入要搜索的数字X。

输出:深度搜索的过程,每个数字以空格间隔,最后一个数字后没有空格,以换行符“\n”结束。

Sample:

input:

20

16 73 22 56 86 84 37 50 83 60 18 18 48 44 70 77 52 72 23 95

18

output:

16 73 56 50 77 52 83 72 23 86 60 95 18

Hint:
如果对以上题目中描述的“二叉树”数据结构,以及深度优先搜索算法不清楚的同学请自行查相关资料进行了解。

允许在DFS.h头文件中定义用于辅助的全局变量。

虽然我们应该习惯于在头文件中声明,在源文件中定义,但是为了我出题方便直接就在头文件中实现DFS函数吧,不好意思。

#include<stdio.h>#include<stdlib.h>#include"DFS.h"#define MAX 50int main() {    int leng = 0;    int arr[MAX] = {0};    int i;    int X = 0;    scanf("%d", &leng);    for (i = 0; i < leng; i++) {        scanf("%d", &arr[i]);    }    scanf("%d", &X);    DFS(arr, leng, 0, X);    return 0;}

读题

my answer

void DFS(int a[], int n, int pos, int x);void DFS(int a[], int n, int pos, int x) {    if (x == a[pos]) {        printf("%d\n", a[pos]);        exit(1);    } else {        printf("%d ", a[pos]);        int index = pos + 1;        if (2 * index <= n) {            DFS(a, n, 2 * index - 1, x);        }        if (2 * index + 1 <= n) {            DFS(a, n, 2 * index, x);        }        return;    }}

the standard answer

#ifndef __DFSFORTREE__#define __DFSFORTREE__#include<stdio.h>#include<stdlib.h>int flag = 0;void DFS(int arr[], int leng, int pos, int theOne) {    if (flag == 0) {        if (pos < leng && arr[pos] != theOne) {            printf("%d ", arr[pos]);            DFS(arr, leng, (pos + 1) * 2 - 1, theOne);            DFS(arr, leng, (pos + 1) * 2, theOne);        } else if (pos < leng && arr[pos] == theOne) {            printf("%d\n", theOne);            flag = 1;        }    }}#endif

反馈

拯救大兵雷诺

新晋的星灵大主教Artanis在目睹了挚友Zeratul的牺牲之后决心对抗黑暗之神Amon。为此,他首先要团结全星区所有种族的力量。

坚定的盟友雷诺和他刚刚结束了Arcturus统治的Terran帝国正在遭受Amon控制的异虫的攻击,帮助他们即可在日后对抗Amon的时候获得帮助。

当星灵部队抵达时,人类的战线已经崩溃,Artanis预测,如果没有星灵的帮助,人类部队将在n单位时间之后彻底战败。异虫部队在战场上建立了m个据点,编号从1到m,要想帮助人类取得胜利,必须击破全部的m个据点。Artanis还预测出了击破第i个据点所需的时间Ti,同时,击破第i个据点会导致异虫的攻势减弱,人类战败的倒计时会增加Ci单位时间。此外,Artanis还计算出了星灵部队战场上任意两点间移动所需的时间Ai,j表示从第i个据点到第j个据点所需的单位时间,0 <= i, j <= m,0表示星灵部队的大本营。

由于Artanis作为大主教还是个新人,指挥能力还不足以发动多线作战,因此他只能从大本营出发,一个一个地摧毁异虫的据点。他现在想知道,在保证人类部队不全军覆没的前提下,有多少种不同的进攻顺序?

输入格式

输入包括m + 4行:

第1行包括2个整数:n和m

第2行包括m个整数:Ti

第3行包括m个整数:Ci

第4至m+4行(共m+1行)是一个(m+1) * (m+1)整数矩阵:Ai,j

整数之间使用空格分隔

输出格式

输出只包含1个整数,即不同的进攻顺序方案数

输出结尾应有一个换行符

数据规模:

0 < n <= 10000, 0 < m <= 10, 0 < Ti, Ci, Ai,j <= 1000

此外,由于星灵拥有诸多人类无法理解的高端技术,因此在据点之间移动所需的时间Ai,j不一定满足三角形不等式,即不保证满足Ai,j <= Ai,k + Ak,j,也不能保证Ai,j = Aj,i,但是Ai,i一定为0

样例输入:

5 3

1 2 3

3 2 1

0 1 1 1

1 0 1 1

1 1 0 1

1 1 1 0

样例输出:

2

样例解释:

只有1 2 3和2 1 3的进攻顺序才能保证倒计时始终在0以上

如果按照1 3 2的顺序来进攻的话,进攻1需要1+1 = 2的时间,还剩下3,又增加3变成6;接下来进攻3需要1+3=4的时间,还剩下2,又增加1变成3;最后进攻2需要1+2=3的时间,倒计时变成0,人类战败。

读题

my answer

#include<stdio.h>2.void game(int i, int A[][11], int C[], int T[], int n, int m, int left, int []);3. 4.int main() {5.    int T[11], C[11], A[11][11], flag[11];6.    int n, m, i, j;7.    scanf("%d%d", &n, &m);8.    for (i = 1; i <= m; i++)9.    scanf("%d", &T[i]);10.    for (i = 1; i <= m; i++)11.    scanf("%d", &C[i]);12.    for (i = 0; i <= m; i++)13.    for (j = 0; j <= m; j++)14.    scanf("%d", &A[i][j]);15.    game(0, A, C, T, n, m, m, flag);16.    return 0;17.}18. 19.void game(int i, int A[][11], int C[], int T[], 20.          int n, int m, int left, int flag[11]) {21.              int j;22.              int * p;23.              p = flag;24.              static int ans = 0;25.              *(p + i) = 0;26.              for (j = 1; j <= m; j++) {27.                  if (m == left) {28.                      for (i = 1; i <= m; i++)29.                      *(p + i) = 1;30.                  }31.        if (i == j || *(p + j) == 0 || n - T[j] - A[i][j] <= 0) continue;32.        else {33.            left--;34.            if (left == 0) {35.                ans++;36.                *(p + j) = 1;37.                return;38.            } else {39.                n = n - T[j] - A[i][j] + C[j];40.                game(j, A, C, T, n, m, left, flag);41.            }42.        }    43.    }44.    if (i == m)45.    printf("%d\n", ans);46.    return;  47.}
#include<stdio.h>void game(int i, int A[][11], int C[], int T[], int n, int m, int left, int []);int main() {    int T[11], C[11], A[11][11], flag[11];    int n, m, i, j;    scanf("%d%d", &n, &m);    for (i = 1; i <= m; i++)    scanf("%d", &T[i]);    for (i = 1; i <= m; i++)    scanf("%d", &C[i]);    for (i = 0; i <= m; i++)    for (j = 0; j <= m; j++)    scanf("%d", &A[i][j]);    game(0, A, C, T, n, m, m, flag);    return 0;}void game(int i, int A[][11], int C[], int T[],           int n, int m, int left, int flag[11]) {              int j;              int * p;              p = flag;              static int ans = 0;              *(p + i) = 0;              for (j = 1; j <= m; j++) {                  if (m == left) {                      for (i = 1; i <= m; i++)                      *(p + i) = 1;                  }        if (i == j || *(p + j) == 0 || n - T[j] - A[i][j] <= 0) continue;        else {            left--;            if (left == 0) {                ans++;                *(p + j) = 1;                return;            } else {                n = n - T[j] - A[i][j] + C[j];                game(j, A, C, T, n, m, left, flag);            }        }        }    if (i == m)    printf("%d\n", ans);    return; }

my answer 2

(加深对递归的理解后..发现这个题其实..挺简单的..

int T[11] = {0}, C[11] = {0}, A[11][11] = {0}, flag[11] = {0};int ans = 0, n, m;void game (int step, int time, int finish);int main() {    int i, j;    scanf("%d%d", &n, &m);    for (i = 1; i <= m; i++)        scanf("%d", &T[i]);    for (i = 1; i <= m; i++)        scanf("%d", &C[i]);    for (i = 0; i <= m; i++)        for (j = 0; j <= m; j++)            scanf("%d", &A[i][j]);    game(0, n, 0);    printf("%d", ans);    return 0;}void game (int step, int time, int finish) {    flag[step] = 1;    int i;    if (finish == m) {        ans++;    } else {        for (i = 0; i <= m; i++) {            if (flag[i] == 0 && A[step][i] + T[i] < time)            game(i, time - A[step][i] - T[i] +  C[i], finish + 1);        }       }    flag[step] = 0;    return;}

the standard answer

#include <stdio.h>2. 3.#define MAXm 114. 5.typedef struct {6.    int x, i, n;7.} str;8. 9.int main() {10.    int m, i, j, t = 0, ans = 0;11.    char visited[MAXm] = { 0 };12.    str stack[MAXm];13.    int A[MAXm][MAXm], T[MAXm], C[MAXm];14.    scanf("%d%d", &stack[0].n, &m);15.    for (i = 1; i <= m; ++i)16.        scanf("%d", T + i);17.    for (i = 1; i <= m; ++i)18.        scanf("%d", C + i);19.    for (i = 0; i <= m; ++i)20.        for (j = 0; j <= m; ++j)21.            scanf("%d", &A[i][j]);22.    stack[0].x = 0;23.    stack[0].i = 0;24.    while (t >= 0) {25.        if (t == m) {26.            ++ans;27.            visited[stack[t].x] = 0;28.            --t;29.        } else {30.            while (++stack[t].i <= m)31.                if (A[stack[t].x][stack[t].i] + T[stack[t].i] < stack[t].n32.                    && !visited[stack[t].i]) {33.                    stack[t+1].i = 0;34.                    stack[t+1].x = stack[t].i;35.                    stack[t+1].n = stack[t].n - A[stack[t].x][stack[t].i]36.                        - T[stack[t].i] + C[stack[t].i];37.                    visited[stack[t++].i] = 1;38.                    break;39.                }40.            if (stack[t].i > m)41.                visited[stack[t--].x] = 0;42.        }43.    }44.    printf("%d\n", ans);45.    return 0;46.}

反馈

在调用子函数时,如果要用到数组,可将数组定义为全局变量,也可以通过指针传递.

0 0