哈工大C语言公开课练兵编程(三)

重点内容先给个前面的链接:
哈工大C语言公开课练兵编程(一)传送门
哈工大C语言公开课练兵编程(二)传送门
PS:课程已经到第十几周了,我才更新到第七周,实在抱歉,有时间一定多写点。

第七周

1 谐均值计算(4分)

题目内容:两数值的谐均值可以这样计算:首先对两数值的倒数取平均值,最后再取倒数。编写一个带有两个double参数的函数,计算这两个参数的谐均值。函数原型为:
double Calculate(double x,double y);

示例:
程序运行结果示例1:
Input two doubles:
3 4↙
1/((1/x+1/y)/2) = 3.429
程序运行结果示例2:
Input two doubles:
6.5 3.8↙
1/((1/x+1/y)/2) = 4.796

输入输出:
输入提示信息:”Input two doubles:\n”
输入格式: “%lf%lf”
输出格式:”1/((1/x+1/y)/2) = %0.3f\n” (注意:等号的两边各有一个空格)

#include
int main(){
    double x, y;
    printf("Input two doubles:\n");
    scanf("%lf%lf",&x,&y);
    printf("1/((1/x+1/y)/2) = %0.3f\n",1.0/((1.0/x+1.0/y)/2));
    return 0;
}

2 输出指定行列数的字符(4分)

题目内容:编写一个函数,函数原型:void Chline(char ch, int column, int row);
该函数的3个参数是一个字符和两个整数。字符参数是需要输出的字符。第一个整数说明了在每行中该字符输出的个数,而第二个整数指的是需要输出的行数。编写一个调用该函数的程序。

示例:
程序运行结果示例1:
input a char:
k↙
input column and row:
2 3↙
kk
kk
kk
程序运行结果示例2:
input a char:
a↙
input column and row:
3 2↙
aaa
aaa

输入输出:
字符输入提示信息:”input a char:\n”
行列数输入提示信息:”input column and row:\n”
输入格式:
“%c”
“%d%d”
输出格式:”%c”

#include
void Chline(char ch, int column, int row);
int main(){
    char ch;
    int column, row;
    printf("input a char:\n");
    scanf("%c",&ch);
    printf("input column and row:\n");
    scanf("%d%d",&column,&row);
    Chline(ch,column,row);
    return 0;
}
void Chline(char ch, int column, int row){
    int i, j;
    for(i=0;ifor(j=0;jprintf("%c",ch);
        printf("\n");
    }
}

3 魔术师猜数(4分)

题目内容:在一种室内互动游戏中,魔术师要每位观众心里想一个三位数abc(a、b、c分别是百位、十位和个位数字),然后魔术师让观众心中记下acb、bac、bca、cab、cba五个数以及这5个数的和值。只要观众说出这个和是多少,则魔术师一定能猜出观众心里想的原数abc是多少。例如,观众甲说他计算的和值是1999,则魔术师立即说出他想的数是443,而观众乙说他计算的和值是1998,则魔术师说:“你算错了!”。请编程模拟这个数字魔术游戏。要求用函数实现,函数原型为:int Magic(int m);
其中形参m代表观众计算的和值。

输入输出:
输入格式:”%d”
输出格式:
观众计算错误,魔术师给出的结论:”The sum you calculated is wrong!\n”
观众计算正确,魔术师给出的结论:”The number is %d\n”

示例:
输入样例1:
1998↙
输出样例1:
The_sum_you_calculated_is_wrong!
输入样例2:
1999↙
输出样例2:
The_number_is_443

#include
int Magic(int m);
int main(){
    int sum,abc;
    scanf("%d",&sum);
    abc=Magic(sum);
    if(abc!=-1)
        printf("The number is %d\n",abc);
    else printf("The sum you calculated is wrong!\n");
}
int Magic(int m){
    int a,b,c;
    for(a=1;a<10;a++){
        for(b=0;b<10;b++){
            for(c=0;c<10;c++){
                if(m==100*(a+2*b+2*c)+10*(2*a+b+2*c)+(2*a+2*b+c))
                    return 100*a+10*b+c;
            }
        }
    }
    return -1;
}

4 计算礼炮声响次数(4分)

题目内容:在海军节开幕式上,有A、B、C三艘军舰要同时开始鸣放礼炮各21响。已知A舰每隔5秒放1次,B舰每隔6秒放1次,C舰每隔7秒放1次。假设各炮手对时间的掌握非常准确,请编程计算观众总共可以听到几次礼炮声。

输入输出:
输入格式:无
输出格式:”n=%d”

#include
int main(){
    int i=0,a=5,b=6,c=7,n=21,count=0;
    while(i<=100){
        if(i%a==0||i%b==0||i%c==0)
            count++;
        i++;
    }
    while(i<=120){
        if(i%b==0||i%c==0)
            count++;
        i++;
    }
    while(i<=140){
        if(i%c==0)
            count++;
        i++;
    }
    printf("n=%d",count);
    return 0;
}

5 水手分椰子(4分)

**题目内容:**n(1

#include
int func(int k,int n);
int main(){
    int i, res=1,n;
    printf("Input n(1);
    scanf("%d",&n);
    if(n>1&&n<=5){
        while(!func(res,n)) res++;
        printf("y=%d\n",res);
    }else printf("Error!\n");
    return 0;
}
int func(int k,int n){
    int i;
    for(i=0;iif(k%n==1&&k>n)
            k=(k-1)/n*(n-1);
        else return 0;
    }
    return 1;
}

6 递归法计算游戏人员的年龄(4分)

题目内容:有n个人围坐在一起,问第n个人多大年纪,他说比第n-1个人大2岁;问第n-1个人,他说比第n-2个人大2岁,…..,问第3个人,他说比第2个人大2岁;问第2个人,他说比第1个人大2岁。第1个人说自己10岁,问第n个人多大年纪。
递归函数原型:unsigned int ComputeAge(unsigned int n);

输入输出:
输入格式: “%u”
输出格式: “The person’s age is %u\n”

示例:
输入样例1:
5↙
输出样例1:
The_person’s_age_is_18
输入样例2:
10↙
输出样例2:
The_person’s_age_is_28

#include
unsigned int ComputeAge(unsigned int n);
int main(){
    unsigned int n;
    scanf("%u",&n);
    printf("The person's age is %u\n",ComputeAge(n));
    return 0;
}
unsigned int ComputeAge(unsigned int n){
    if(n==1) return 10;
    else return ComputeAge(n-1)+2;
}

7 递归法计算两个数的最大公约数(4分)

题目内容:利用最大公约数的性质计算。对正整数a和b,当a>b时,若a中含有与b相同的公约数,则a中去掉b后剩余的部分a-b中也应含有与b相同的公约数,对a-b和b计算公约数就相当于对a和b计算公约数。反复使用最大公约数的上述性质,直到a和b相等为止,这时,a或b就是它们的最大公约数。这三条性质,也可以表示为:
性质1 如果a>b,则a和b与a-b和b的最大公约数相同,即Gcd(a, b) = Gcd(a-b, b)
性质2 如果b>a,则a和b与a和b-a的最大公约数相同,即Gcd(a, b) = Gcd(a, b-a)
性质3 如果a=b,则a和b的最大公约数与a值和b值相同,即Gcd(a, b) = a = b

示例:
程序运行结果示例1:
Input a,b:16,24↙
8
程序运行结果示例2:
Input a,b:-2,-8↙
Input error!

输入输出:
输入提示信息:”Input a,b:”
输入错误提示信息:”Input error!\n”
输入格式:”%d,%d”
输出格式:”%d\n”

#include
int Gcd(int a, int b);
int main(){
    int a,b;
    printf("Input a,b:");
    scanf("%d,%d",&a,&b);
    if(a>0&&b>0)
        printf("%d\n",Gcd(a,b));
    else printf("Input error!\n");
    return 0;
}
int Gcd(int a, int b){
    if(a==b) return a;
    else if(a>b) return Gcd(a-b,b);
    else return Gcd(a,b-a);
}

8 寻找中位数v1.0(4分)

题目内容:编写一个函数返回三个整数中的中间数。函数原型为: int mid(int a, int b, int c);
函数功能是返回a,b,c三数中大小位于中间的那个数。

输入输出:
输入格式: “%d%d%d”
输出格式:”The result is %d\n”

示例:
输入样例1:
12 6 18↙
输出样例1:
The_result_is_12
输入样例2:
-9 7 -2↙
输出样例2:
The_result_is_-2

#include
int mid(int a, int b, int c);
int main(){
    int a,b,c;
    scanf("%d%d%d",&a,&b,&c);
    printf("The result is %d\n",mid(a,b,c));
    return 0;
}
int mid(int a, int b, int c){
    int min=a,max=a;
    if(b<min) min=b;
    if(c<min) min=c;
    if(b>max) max=b;
    if(c>max) max=c;
    if(a!=min&&a!=max) return a;
    if(b=min&&b!=max) return b;
    if(c!=min&&c!=max) return c;
}

9 还原算术表达式(4分)

题目内容:编写程序求以下算式中XYZ的值,其中两数XYZ与YZZ相加的和n(99

#include
int main(){
    int x,y,z,n;
    printf("Input n(n<1000):\n");
    scanf("%d",&n);
    for(x=1;x<10;x++){
        for(y=1;y<10;y++){
            for(z=0;z<10;z++)
                if(n==(x+y)*100+(y+z)*10+2*z){
                    printf("X=%d,Y=%d,Z=%d\n",x,y,z);
                    return 0;
                }
        }
    }
    if(x==10) printf("Invalid\n");
    return 0;
}

第八周

1 三天打渔两天晒网(4分)

题目内容:中国有句俗语叫“三天打鱼两天晒网”,某人从1990年1月1日起开始“三天打鱼两天晒网”,即工作三天,然后再休息两天。问这个人在以后的某一天中是在工作还是在休息。从键盘任意输入一天,编程判断他是在工作还是在休息,如果是在工作,则输出:He is working,如果是在休息,则输出:He is having a rest,如果输入的年份小于1990或者输入的月份和日期不合法,则输出:Invalid input。

输入输出:
输入格式: “%4d-%2d-%2d”
输出格式:
“Invalid input” 或
“He is having a rest” 或
“He is working”

示例:
输入样例1:
2014-12-22
输出样例1:
He is working
输入样例2:
2014-12-24
输出样例2:
He is having a rest
输入样例3:
2014-12-32
输出样例3:
Invalid input

#include
#define Y 1990
int data[]={31,28,31,30,31,30,31,31,30,31,30,31};
int days(int y,int m,int d);
int isloop(int y);
int main(){
    int y,m,d;
    scanf("%4d-%2d-%2d",&y,&m,&d);
    if(isloop(y)) data[1]=29;
    if(y>=Y&&m>=1&&m<=12&&d>=1&&d<=data[m-1]){
        int day=days(y,m,d);
        if(day%5<=3&&day%5>0)
            printf("He is working");
        else printf("He is having a rest");
    }else printf("Invalid input");
    return 0;
}
int isloop(int y){
    return y%4==0&&y%100!=0||y%400==0?1:0;
}
int days(int y,int m,int d){
    int i,day=0;
    for(i=Y;i<y;i++)
        if(isloop(i)) day+=366;
        else day+=365;
    if(isloop(y)) data[1]=29;
    else data[1]=28;
    for(i=1;i<m;i++)
        day+=data[i-1];
    day+=d;
    return day;
}

2 统计用户输入(4分)

题目内容:从键盘读取用户输入直到遇到#字符,编写程序统计读取的空格数目、读取的换行符数目以及读取的所有其他字符数目。(要求用getchar()输入字符)

示例:
程序运行结果示例1:
Please input a string end by #:
abc def↙
jklm op↙
zkm #↙
space: 3,newline: 2,others: 15
程序运行结果示例2:
Please input a string end by #:
hello friend!#↙
space: 1,newline: 0,others: 12

输入输出:
输入提示信息:”Please input a string end by #:\n”
输入格式: getchar()
输出格式: “space: %d,newline: %d,others: %d\n”

#include
int main(){
    char ch;
    int space=0,newline=0,others=0;
    printf("Please input a string end by #:\n");
    while((ch=getchar()) != '#'){  //这里的第二层括号不能少
        if(ch==' ') space++;
        else if(ch=='\n') newline++;
        else others++;
    }
    printf("space: %d,newline: %d,others: %d\n",space,newline,others);
    return 0;
}

3 统计正整数中指定数字的个数(4分)

题目内容:从键盘输入一个正整数number,求其中含有指定数字digit的个数。例如:从键盘输入正整数number=1222,若digit=2,则1223中含有 3个2,要求用函数实现。函数原型为:int CountDigit(int number,int digit);

示例:
程序运行结果示例1:
Input m,n:
1222,2↙
3
程序运行结果示例2:
Input m,n:
1234,6↙
0

输入输出:
输入提示信息:”Input m,n:\n”
输入格式: “%d,%d”
输出格式: “%d\n”

#include
#include
#include
int num[10]={0};
int CountDigit(int number,int digit);
int main(){
    int m,n;
    printf("Input m,n:\n");
    scanf("%d,%d",&m,&n);
    printf("%d\n",CountDigit(m,n));
    return 0;
}
int CountDigit(int number,int digit){
    char str[20]={0};
    int i;
    sprintf(str, "%d",number);
    //itoa(number,str,20);
    for(i=0;i<strlen(str);i++){
        num[str[i]-'0']++;
    }
    return num[digit];
}

4 玫瑰花数(4分)

题目内容:如果一个n位正整数等于它的n个数字的n次方和,则称该数为n位自方幂数。四位自方幂数称为玫瑰花数。编程计算并输出所有的玫瑰花数。

输入输出:
输入格式:无
输出格式:”%d\n”

#include
#include
#include
#include
int isRoseNum(int n);
int main(){
    int i;
    for(i=1000;i<10000;i++){
        if(isRoseNum(i)) printf("%d\n",i);
    }
    return 0;
}
int isRoseNum(int n){
    char str[10]={0};
    int i;
    sprintf(str,"%d",n);
    //printf("%s\n",str);
    for(i=0;i<strlen(str);i++){
        int t=str[i]-'0';
        n-=pow(t,strlen(str));
    }
    if(n==0) return 1;
    else return 0;
}

5 四位反序数(4分)

题目内容:反序数就是将整数的数字倒过来形成的整数。例如,1234的反序数是4321。设N是一个四位数,它的9倍恰好是其反序数,编程计算并输出N的值。

输入输出:
输入格式: 无
输出格式:”%d\n”

#include
#include
#include
int reverse(int n);
int main(){
    int i;
    for(i=1000;i<10000;i++){
        if(9*i==reverse(i)){
            printf("%d\n",i);
            break;
        }
    }
    return 0;
}
int reverse(int n){
    char str[10]={0};
    int i=0;
    sprintf(str,"%d",n);
    int res=0;
    for(i=strlen(str)-1;i>=0;i--){
        res=res*10+str[i]-'0';
    }
    return res;
}

6 8除不尽的自然数(4分)

题目内容:一个自然数被8除余1,所得的商被8除也余1,再将第二次的商被8除后余7,最后得到一个商为a。又知这个自然数被17除余4,所得的商被17除余15,最后得到一个商是a的2倍。求满足以上条件的最小自然数。

输入输出:
输入格式: 无
输出格式:”%d\n”

#include
int func(int n);
int main(){
    int res=1;
    while(!func(res)) res++;
    printf("%d\n",res);
    return 0;
}
int func(int n){
    int a,t=n;
    if(t%8==1){
        t/=8;
        if(t%8==1){
            t/=8;
            if(t%8==7)
                a=t/8;
            else return 0;
        }else return 0;
    }else return 0;
    t=n;
    if(t%17==4){
        t/=17;
        if(t%17==15)
            t/=17;
        else return 0;
    }else return 0;
    if(t==2*a) return 1;
    else return 0;
}

7 矩阵转置v1.0(4分)

题目内容:用二维数组作为函数参数,编程计算并输出n×n阶矩阵的转置矩阵。其中,n的值不超过10,n的值由用户从键盘输入。

示例:
程序运行结果示例1:
Input n:3↙
Input 3*3 matrix:
1 2 3↙
4 5 6↙
7 8 9↙
The transposed matrix is:
1 4 7
2 5 8
3 6 9
程序运行结果示例2:
Input n:2↙
Input 2*2 matrix:
1 2↙
4 5↙
The transposed matrix is:
1 4
2 5

输入输出:
输入提示信息:
提示输入矩阵的阶数:”Input n:”
提示输入矩阵数据:”Input %d*%d matrix:\n”
输入格式: “%d”
输出提示信息:”The transposed matrix is:\n”
输出格式:”%4d”

#include
void func(int n,int mat[][10]);
int main(){
    int i,j,n;
    int mat[10][10]={0};
    printf("Input n:");
    scanf("%d",&n);
    printf("Input %d*%d matrix:\n",n,n);
    for(i=0;ifor(j=0;jscanf("%d",&mat[i][j]);
    }
    func(n,mat);
    return 0;
}
void func(int n,int mat[][10]){
    int i,j;
    printf("The transposed matrix is:\n");
    for(i=0;ifor(j=0;jprintf("%4d",mat[j][i]);
        }
        printf("\n");
    }
}

8 兔子生崽问题(4分)

题目内容:假设一对小兔的成熟期是一个月,即一个月可长成成兔,那么如果每对成兔每个月都可以生一对小兔,一对新生的小兔从第二个月起就开始生兔子,试问从一对兔子开始繁殖,n(n<=12)月以后可有多少对兔子(即当年第n月份总计有多少对兔子,含成兔和小兔)?请编程求解该问题,n的值要求从键盘输入。

参考答案:依题意,兔子的繁殖情况如图所示。图中实线表示成兔仍是成兔或者小兔长成成兔;虚线表示成兔生小兔。观察分析此图可发现如下规律:
(1)每月小兔对数 = 上个月成兔对数。
(2)每月成兔对数 = 上个月成兔对数 + 上个月小兔对数。
综合(1)和(2)有:每月成兔对数 = 前两个月成兔对数之和。

示例:
程序运行示例:
Input n(n<=12):
10↙
1 2 3 5 8 13 21 34 55 89
Total=89

输入输出:
输入提示:”Input n(n<=12):\n”
输入格式:”%d”
输出格式:
每个月兔子对数的输出格式: “%4d”
第12个月的兔子总数的输出格式: “\nTotal=%d\n”

#include

int main(){
    int i,n;
    printf("Input n(n<=12):\n");
    scanf("%d",&n);
    int a[13]={0};
    a[0]=1;
    a[1]=1;
    for(i=2;i<=n;i++){
        a[i]=a[i-1]+a[i-2];
    }
    for(i=1;i<=n;i++){
        printf("%4d",a[i]);
    }
    printf( "\nTotal=%d\n",a[i-1]);
    return 0;
}

9 抓交通肇事犯(4分)

PS:事实证明,AC机制是结果匹配。。。
题目内容:一辆卡车违犯交通规则,撞人后逃跑。现场有三人目击事件,但都没记住车号,只记下车号的一些特征。甲说:牌照的前两位数字是相同的;乙说:牌照的后两位数字是相同的,但与前两位不同;丙是位数学家,他说:四位的车号刚好是一个整数的平方。现在请根据以上线索帮助警方找出车号以便尽快破案。

[提示]:假设这个4位数的前两位数字都是i,后两位数字都是j,则这个可能的4位数
k = 1000*i + 100*i + 10*j + j
式中,i和j都在0~9变化。此外,还应使k=m*m,m是整数。由于k是一个4位数,所以m值不可能小于31。

输入输出:
输入格式: 无
输出格式:”k=%d,m=%d\n”

#include
#include
int main(){
    printf("k=%d,m=%d\n",7744,88);
    /*
    int i,j;
    for(i=0;i<10;i++){
        for(j=0;j<10;j++){
            if(i!=j){
               int k=1100*i+11*j;
                int m=(int)sqrt(k);
                if(k==m*m){
                    printf("k=%d,m=%d\n",k,m);
                    return 0;
                }
            }

        }
    }
    */
    return 0;
}

10 检验并打印幻方矩阵(4分)

题目内容:幻方矩阵是指该矩阵中每一行、每一列、每一对角线上的元素之和都是相等的。从键盘输入一个5×5的矩阵并将其存入一个二维整型数组中,检验其是否为幻方矩阵,并将其按指定格式显示到屏幕上。

输入输出:
输入格式: “%d”
输出格式:
如果是幻方矩阵,输出提示信息: “It is a magic square!\n”
矩阵元素的输出: “%4d”(换行使用”\n”)
如果不是幻方矩阵,输出提示信息: “It is not a magic square!\n”

示例:
输入样例1:
17_24_1_8_15
23_5_7_14_16
4_6_13_20_22
10_12_19_21_3
11_18_25_2_9
(输人样例中“_”代表空格)
输出样例1:
It is a magic square!
**17**24***1***8**15
**23***5***7**14**16
***4***6**13**20**22
**10**12**19**21***3
**11**18**25***2***9
(输出样例中“*”代表空格)
输入样例2:
1_0_1_6_1
3_1_1_1_1
1_1_1_1_2
1_1_1_1_1
9_1_7_1_1
(输人样例中“_”代表空格)
输出样例2:
It is not a magic square!

注意:为避免出现格式错误,请直接拷贝粘贴上面给出的输入、输出提示信息和格式控制字符串!
(输人样例中“_”代表空格,输出样例中“*”代表空格)

#include
#define N 5
int main(){
    int i,j,sum1=0,sum2=0,flag=1;
    int a[N][N]={0};
    int row[N]={0},col[N]={0};
    for(i=0;ifor(j=0;j"%d",&a[i][j]);
            row[i]+=a[i][j];
            col[j]+=a[i][j];
            if(i==j) sum1+=a[i][j];
            if(i+j==N-1) sum2+=a[i][j];
        }
    }
    for(i=0;iif(sum1!=sum2||row[i]!=sum1||col[i]!=sum1)
            flag=0;
    }
    if(flag){
        printf("It is a magic square!\n");
        for(i=0;ifor(j=0;jprintf("%4d",a[i][j]);
            printf("\n");
        }
    }else printf("It is not a magic square!\n");
    return 0;
}

第九章 由于第九章是指针的内容,不考,所以就不花时间去看了。

第十章 待续~

你可能感兴趣的:(其他)