(西农C语言程序设计练习题解)

第一章C语言程序设计概述

题目1 输出字符串"您好,中国!"

输出字数串"您好!中国!"
输入格式:
本题无输入
输出格式:
在一行中输出"您好,中国!"
输入样例:
在这里给出一组输入。例如:

输出样例:
在这里给出相应的输出。例如:
您好,中国!
#include<stdio.h>
int main()
{
    printf("您好,中国!\n");
    return 0;
}

题目2 输出如下图形(鱼)

编写一个C语言程序,输出如下图形(鱼)
输入格式:

输出格式:
输入样例:

输出样例:
在这里给出相应的输出。例如:
** *
******* **
********* ***
************** ****
******@***************
************** ****
********* ***
******* **
** *
#include<stdio.h>
int main()
{
    printf("        **           *\n");
    printf("      *******       **\n");
    printf("     *********     ***\n");
    printf("  **************  ****\n");
    printf("******@***************\n");
    printf("  **************  ****\n");
    printf("     *********     ***\n");
    printf("      *******       **\n");
    printf("        **           *\n");
    return 0;
}

题目3 期末考试总评

Keven 刚刚考完了 C语言 期末考试,并且他知道总评分数的计算公式如下:
总评分数 = 平时分 × 0.3 + 期中考试分数 × 0.2 + 期末考试分数 × 0.5
现在 Keven 已经知道了自己的平时分、期中考试分数和期末考试分数,他希望你帮他计算他最后的总评成绩。
输入格式:
输入在一行中给出3.个以空格分隔的正整数 a, b, c (1<= a, b, c<=100)
分别表示 Keven 的平时分,期中考试成绩,期末考试成绩。
输出格式:
在一行中输出 Keven 的C语言的总评成绩。(保留一位小数)
输入样例:
100 100 100
输出样例:
100.0
(为什么 Keven 会提前知道自己期末考试分数呢?因为试卷上所有的错误题目都是 Keven 故意做错的)
#include<stdio.h>
int main()
{
    int a,b,c;
    scanf("%d %d %d\n",&a,&b,&c);
    double s;
    s=a*0.3+b*0.2+c*0.5;
    printf("%.1lf\n",s);
    return 0;
}

第二章 C语言基础

题目5-1逻辑表达式

写出判断ch是空格或者回车的逻辑表达式
分数 1
作者 颜晖单位 浙大城市学院
假设变量已正确定义并赋值,写出满足下列条件的C语言表达式。
ch 是空格或者回车:
/*空格和回车都属于字符,单引号来表示字符,\n表示回车*/
ch==' ' || ch=='\n'

题目5-2 将数字字符转换成数字

要求填入一个表达式,可将输入的数字字符转换成对应的数字输出。例如:输入数字字符3,输出数字3。
#include <stdio.h>
int main()
{ char ch;
  int value;
  scanf("%c",&ch);
/*value为实际表示数字字符的数字,ch为字符,ch-value='0'-0 
value=ch+0-'0';
实际上这里的0-'0'=-48;读者可自主查阅ASCII码表*/
  value=ch-48;
  printf("%d",value);
  return 0;
}

题目5-3大写转小写(表达式)

大写转小写(表达式)

下面的程序输入大写字母,输出对应的小写字母。请在空白处填写表达式完成该程序。

#include <stdio.h>

int main()
{
    char lower, upper;
    upper = getchar();
/*65~90为26个大写字母,97~122为26个小写字母,对应字母的大小写相差'a'-'A'=32*/
    lower = upper+32;
    putchar(lower);
    putchar('\n');
    return 0;
}

题目5-4 从键盘输入两个实数,计算表达式的值

从键盘输入两个实数,计算表达式

的值

#include<stdio.h>
#include<math.h>
/*引用函数库,为使用后文的 
绝对值函数fabs()和函数pow()做准备*/ 
int main(){
float x,y,z;
printf("请输入实型变量x和y的值,x不等于y:\n");
scanf("%f %f",&x,&y);
z=fabs(y)/(2*x+4*pow(y,x));
printf("z=%f\n",z);
return 0;
}

题目5-5 写出判断数字字符的逻辑表达式

假设变量已正确定义并赋值,写出满足下列条件的C语言表达式。

ch是数字字符:

/*ASCII码表中数字字符'0'~'9'码值为48~57

可以直接这样

ch>='0' && ch<='9';

也可以

ch>=48 && ch<=57;

本题主要考察ACSII码表中数字表示码值,逻辑判断符号“且”的使用

*/

题目6-2 环形解密

将26个英文字母按顺时针方向排成一个圆环。密钥是一个整数。
具体加密方法如下:
若密钥 key≥0,则从明文字母开始按顺时针方向走 ∣key∣ 步得到密文字母;
若密钥 key<0,则从明文字母开始按逆时针方向走 ∣key∣ 步得到密文字母。
下面的程序输入明文和密钥,输出密文。请在空白处填写适当内容完成该程序
输入格式
明文(小写字母) 密钥(任意整数)
输出格式
密文(小写字母)
输入样例1
x 5
输出样例1
c
输入样例2
b -3
输出样例2
y
#include <stdio.h>
#include <stdio.h>
int main()
{
    char plain, secret;
    int key;
    scanf(" %c %d", &plain, &key);
    secret=((plain-'a'+(key%26)+26)%26)+'a';/*实际上原题只需要输入这一行,其它行系统已给*/
/*这里key取余后可以将其控制在-26~26数字范围内,
再将取余之后的数字+26,可以保障得到来做循环的数字为0~26的正数,
将plain-'a'得到从0开始的循环。*/
    printf("%c\n", secret);
    return 0;
}

题目7-1 拆数

从键盘输入一个三位的正整数,输出它的各位之和与积。
输入样例:
358
输出样例:
在一行中输出结果,用一个半角空格隔开,行尾无空格。
16 120
#include<stdio.h>
int main()
{
    int a,b,c;
/*将一个整数除以10取余可得到这个数的个位数a%10
将一个三位数除以一百,由于是整型int也会得到一个整数为该三位数的百位数a/100
先将三位数除以100取余会得到后面两位数,再将后面两位数/10取整得到这个三位数的十分位*/
    scanf("%d",&a);
    b=(a%100)/10+(a/100)+a%10;
    c=((a%100)/10)*(a/100)*(a%10);
    printf("%d %d\n",b,c);
    return 0;
}

题目7-2 温度单位转换

从键盘读取华氏温度,转换成摄氏温度并输出,保留1位小数。
转换公式为:c=5/9*(f-32), 其中,f为华氏温度,c为摄氏温度。
输入格式:
华氏温度
输出格式:
摄氏温度
输入样例:
100
输出样例:
37.8
#include<stdio.h>
int main()
{
    double f,c;
    scanf("%lf",&f);
/*本题主要涉及到数据类型的隐式转换
5/9=0;
  所以需要将9改为9.0使得这个分数转换为double类型,f,c本身定义为double类型
当然定义为float类型也可以。
  float和double都属于浮点型,float为单精度浮点型,double为双精度浮点型。
  就像int型输入输出用%d那样,float型输入输出用%f,double型输入输出用%lf,但习惯上double和float类型输出也就是打印函数printf都可以用%f。

*/
    c=5/9.0*(f-32);
    printf("%.1lf",c);//最后结果输出的时候,double类型可用%f或%lf,保留n位小数可表示为%.nlf
    return 0;
}

题目 7-3 菲姐游泳

游泳奥运冠军菲姐刻苦训练,从早上a时b分开始下水训练,直到当天的c时d分结束。请编程计算:菲姐当天一共训练多少小时多少分钟?
输入格式:
一行之内输入以空格分隔的4个非负整数,分别对应a,b,c,d。其中,0 ≤a<c ≤24;b和d均不大于60。
输出格式:
h:m。其中,整数h表示小时数,整数m表示分钟数,m应小于60。
输入样例:
6 30 23 20
输出样例:
16:50
#include<stdio.h>
int main()
{
    int a,b,c,d,s;
    scanf("%d %d %d %d\n",&a,&b,&c,&d);
//本题设计的主要是时钟制做差得到时钟制的差值,可以先将小时数乘以60加上分钟数,得到两个时间点的分钟数差值
//再将得到的差值除以60取余得到分钟数,除以60取整得到小时数(注意要定义为int类型)
    s=c*60+d-a*60-b;
    printf("%d:%d",s/60,s%60);
    return 0;
}

第一二章单元测验

选择题

题目2-1

C程序是由函数构成的

C程序实际上是由一个main函数和若干子函数组成。

题目2-2

(1)在C语言中分号表示一个语句的结束,是C语句的必要组成部分

(2)在C语句的后面可以加//之后来描述注释,如果一行不够输入,也可以用/* */在中间描述注释

(3)在C语言中,main这个词是主函数名,不能修改。

(4)函数是C程序的基本单位。

题目2-3

C语言程序的执行,总是起始于main函数。

题目2-4

开发一个C程序的一般过程是编辑、编译、连接和执行.

题目2-5

38可以作为普通的十进制常量

038以0开头,按理应该是八进制数,但八进制数最大数应该为7,不能出现8,不合法

3E8表示3*10^8,实型常量(E的前面必须有数字,E的后面必须是整数)

"\38"为转义字符合法

题目2-6

putchar是c语言的一个输出函数

putchar(c),其中c表示字符或者该字符的ascii码值,

对于'\15',我们首先要知道转义字符\ddd(d表示数字)表示\后面的数字为八进制,也就是说最终它将输出8进制数15所对应的十进制数对应的ascii值的相应的字母(这句有点绕口哈)

15就是十进制数,最终输出对应ascii码字母

017为八进制数转化为十进制就是15

'\xf'为转义字符\x后面为16进制数f为15

题目2-7

34/5计算机会自动取整为6

题目2-8

注意到别的数据类型与double类型做了加法,最终将保留为double类型

题目2-9

能正确表示逻辑关系:“x≥10或x≤0” 的C语言表达式是 x>=10 || x<=0 ,其中||表示或

题目2-10

以下变量x、y、z均为double类型且已正确赋值,不能正确表示数学式子x/(y*z)的C语言表达式是(A)

A.

x/y*z

B.

x* (1/( y*z ))

C.

x/y*1/z

D.

x/y/z

本题主要考察各个运算符的优先级

题目2-11

设 a、b、c、d、m、n均为 int型变量,且 a=5、b=6、c=7、d=8、m=2、n=2,则逻辑表达式 (m=a>b)&&(n=c>d)运算后,n的值不变

很抱歉各位,之前这里小郭理解错了,给大家带来了不便,这里纠正一下。

首先我们应该明白,各种运算符的优先级是算术运算、关系运算、赋值运算

这里’>‘为关系运算符,优先级要高于=’这个赋值运算符,所以我们先将a与b的值作比较,显然a>b是不成立的,该关系运算会返回整型0,然后将0的值赋给m,赋值运算的返回值可以认为就是所赋的值,而‘0’意味着假,对于与的逻辑运算会出现短路,不会再往下运算。所以后面的各种运算并没有执行,所以n的值是不变的。

题目2-12

执行下面的语句后,变量 a 的值为 ▁▁▁▁▁。

a = 1, 2, 3, 4;

这里会先将1的值赋给a,然后做逗号运算,(1,2)的结果为2,结果继续逗号运算(2,3)结果为3,继续做逗号运算(3,4)最终运算结果为4,但过程中只给a赋了一次值1。

这里如果有一个printf语句,如图,它的结果

题目2-13

变量名不能出现&,不能以数字开头,不能出现与C语言原有数据类型名等重复的名字,short属于短整型数据名,不合法

题目2-14

int a,b=0;只给b赋值为0,a没有初始值,它的值为a申请地址的原有数据,是随机的。

题目2-15

以下运算符优先级按从高到低排列正确的是算术运算、关系运算、赋值运算

题目2-16

printf(“%5.2f”,4321.5678);的输出结果是

这里.2保留两位小数,占据5个宽度,但4321.56大于五个宽度,宽度设置无效,输出结果为4321.56

我们这里用几个代码图解细讲一下输出宽度规则

(1)

注意到第一个数字设置了6个宽度保留一位小数,22.2只占了4个宽度,它会在前面补两个空格

(2)

注意到数字设置了3个宽度,但保留小数后的数字222.2占据5个宽度宽度不够怎么办?不够它会直接填充,宽度设置无效

题目2-17

int m,n; scanf("m=%d,n=%d",&m,&n); 若想让m的值为100,n的值为200,正确的数据输入m=100,n=200

题目7-1 计算三位数每位数字立方和

题目描述:请输入一个三位数的整数,计算该整数的每位数字以及它们的立方和,并将结果输出。
输入格式:
输入一个三位数的整数
输出格式:
第一行分别输出百位,十位,个位(使用英文逗号间隔)
第二行输出每位数字的立方和
输入样例:
在这里给出一组输入。例如:
125
输出样例:
在这里给出相应的输出。例如:
1,2,5
134
#include<stdio.h>
int main()
{
    int s;
    scanf("%d",&s);
    int a,b,c,d;//这里定义该三位数的百分位,十分位,个位,立方和分别为a,b,c,d
    a=s/100;
    b=(s/10)%10;
    c=s%10;
    d=a*a*a+b*b*b+c*c*c;
    printf("%d,%d,%d\n%d",a,b,c,d);//这里输出注意题干要求用英文逗号隔开,还要\n换行
    return 0;
}

题目7-2 计算两点之间的距离

题目要求从键盘输入两个点的坐标x1、y1、x2、y2,然后输出它们之间的距离。
输入格式:
在一行中输入4个整数,用空格分开。
输出格式:
输出单独占一行,计算结果显示2位小数。
输入样例:
2 5 -1 3
输出样例:
3.61
#include<stdio.h>
#include<math.h>//这里引用标准函数库,为下面开平方准备
int main()
{
    int x1,x2,y1,y2;
    scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
    double s;
    s=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));//这里是一个简单的距离坐标公式
    printf("%.2f",s);//输出要求保留两位小数
    return 0;
}

第三章 程序设计基本结构

题目 5-02 找出3个数中最大的数[2]

#include <stdio.h>
int main()
{
    int a, b, c, max;

    scanf("%d %d %d", &a, &b, &c);
    max = 0;
    if ( a > b ) {
        if ( a > c ) {
            max = a;
        } else {
            max = c;
        }
    } else {
        if  (b>c) {
            max = b;
        } else {
            max = c;
        }
    }
    printf("%d\n", max);
    return 0;
}

题目 5-03 判断是否是三角形以及其是哪一种三角形

请编程从键盘上输入3个整数(用空格分隔),判断这3个数是否可以构成一个三角形(条件:三条边均大于0且任意两边之和均大于第三边),如果可以则进一步判断是等边、等腰还是一般三角形。若为等边三角形输出"1",若为等腰三角形输出"2",若为一般三角形输出"3",若无法组成三角形输出"-1"。
#include <stdio.h>
int main(void)
{
int x,y,z;
scanf("%d %d %d",&x,&y,&z);
if(x+y>z && x+z>y && y+z>x)//能构成三角形
   {if(x==y && y==z)  //等边三角形
     printf("1\n");
    else
      if(x==y || x==z || y==z)//等腰三角形
        printf("2\n");
      else
        printf("3\n");//一般三角形
   }
else//不能构成三角形
    printf("-1\n");
    return 0;
}

题目 5-04 体型判断

体指数 t = 体重w /(身高h * 身高h )
w单位为千克,h单位为米
当 t < 18 时,为低体重;
当 t 介于18和25之间时,为正常体重;
当 t 介于25和27之间时,为超重体重;
当 t >=27 时,为肥胖。
从键盘输入你的身高h和体重w,根据上述给定的公式计算体指数,然后判断你的体重属于何种类型。
请补全代码实现上述功能。(请不要添加多余的空格)
#include <stdio.h>
int main()
{
    float h, w, t;
    scanf("%f,%f", &h,&w);
    t=w/(h*h);
    if(t<18)
        printf("t=%f,低体重!",t);
    else if(t<25)
        printf("t=%f,正常体重!",t);
    else if(t<27)
        printf("t=%f,超重体重!",t);
    else
        printf("t=%f,肥胖!",t);
    return 0;
}

题目 5-05 求方程的根

请完善程序,实现以下程序功能:从键盘上输入a、b、c三个系数的值(双精度实数),求方程的根并输出。

输入样例1:

5 9 2

输出样例1:

x1=-0.26

x2=-1.54

输入样例2:

9 2 6

输出样例2:

x1=-0.11+0.81i

x2=-0.11-0.81i
#include <stdio.h>
#include <math.h>
int main(void)
{int i;for(i=1;i<=3;i++){ //该循环用于自动阅卷,请考生忽略
double a,b,c,d,x1,x2;
scanf("%lf%lf%lf",&a,&b,&c);
d=b*b-4*a*c;
if(d>=0)//两个实根
  {x1=(sqrt(b*b-4*a*c)-b)/(2*a);
   x2=(-sqrt(b*b-4*a*c)-b)/(2*a);
   printf("x1=%.2lf\nx2=%.2lf\n",x1,x2);
  }
else//输出两个共轭复根,结果保留两位小数
  {printf("x1=%.2lf+%.2lfi\n",-b/(2*a),sqrt(4*a*c-b*b)/(2*a));//输出形如x1=a+bi的形式并换行
   printf("x2=%.2lf-%.2lfi\n",-b/(2*a),sqrt(4*a*c-b*b)/(2*a));//输出形如x2=a-bi的形式并换行
  }
    } //该循环用于自动阅卷,请考生忽略
 return 0;
} 

题目 5-06 显示扑克牌[2]

在玩牌程序中,每一组牌用数字1〜13代表。输入数字,显示相应的牌。其中2〜10直接显示数字,而数字1、11、12、13则分别用Ace、Jack、Queen、King来表示。
#include <stdio.h>
int main()
{
    int n;
    scanf("%d", &n);
    if(n >= 1 && n <= 13){
        switch(n){
            case 1: printf("Ace\n");break;
            case 11: printf("Jack\n"); break; 
            case 12: printf("Queen\n"); break; 
            case 13: printf("King\n"); break; 
            default: printf("%d\n",n);break;
        }
    }else{
        printf("Error\n");
    }
    return 0;
}

题目 5-08 switch改写成if-else

写出与以下switch语句等价的else-if语句。
switch (ch){
    case '-':
        minus++;
    case '+':
        plus++; break; 
    case '0' : case '1' : case '2' : case '3' : case '4' :
    case '5' : case '6' : case '7' : case '8' : case '9' : 
        digit ++;break;
    default: 
        other ++; break; 
} 
if (ch=='-'){ 
    minus++;plus++;
}else if (ch=='+'){
    plus ++;
}else if (ch>='0' && ch<='9'){
    digit ++;
}else{
    other++;
}

题目 5-09 输入年月日,计算这一天是这一年的第多少天。

输入年月日,计算这一天是这一年的第多少天。
#include <stdio.h>
int main()
{
    int year, month, day, daysum = 0;
    scanf ("%d %d %d", &year,&month,&day); 
    if (month < 1 || month > 12 || day < 1 || day > 31)
    {
            printf ("Date Invalid!\n");
        
    return 0;
    }
    switch (month-1)
    {
        case 11: daysum += 30;
        case 10: daysum += 31;
        case 9:  daysum += 30;
        case 8:  daysum += 31;
        case 7:  daysum += 31;
        case 6:  daysum += 30;
        case 5:  daysum += 31;
        case 4:  daysum += 30;
        case 3:  daysum += 31;
        case 2:  
            if ((year%4==0 && year%100!=0) || (year%400==0))
                daysum += 29;
            else
                daysum += 28;
        case 1:  daysum += 31;
        default: break;
    }
    daysum+=day;;
    printf ("%d\n", daysum);
    return 0;
}

题目 5-11 在屏幕上输出如下所示的九九乘法表:

编写程序,在屏幕上输出如下所示的九九乘法表:
#include<stdio.h>
int main()
{
    int i,j;    
    for(i=1;i<=9;i++)
    {
        printf("%-4d",i);
    }
    printf("\n");
    printf("--------------------------------------------\n");
    for(i=1;i<=9;i++)
    {
        for(j=1;j<i;j++)//控制每个输出数字前输出的空格
        {
            printf("    ");
        }
        for(j=i;j<=9;j++)
        {
            printf("%-4d",i*j);            
        }
        printf("\n");
    }    
    return 0;
}

题目 5-12每位数字之和

编写程序从键盘输入一个无符号整数,输出它的各位数字之和。如输入1476,则输出格式为:6+7+4+1=18。
#include<stdio.h>
int main()
{    
    unsigned  a;
    int sum=0;
    scanf("%u",&a);
    while(a)
    {
        int x;
        x=a%10;  
        sum+=x;
        a=a/10;
        if(a!=0)
            printf("%d+",x);
        else
            printf("%d",x);     
    }
    printf("=%d\n",sum);
    return 0;
}

题目 5-13 计算s = 1/1! + 1/2! + 1/3! + …+ 1/n!的值

下面的程序计算 s=1!1+2!1+3!1+⋯+ n!1的值。请将程序中缺失的表达式补充上。
#include <stdio.h>
int main()
{
    int i,n;
    double f=1;
    double s=0;
    scanf("%d",&n);
    for (i=1; i<=n;i++)
    {
        f=f*(1/(i*1.0));
        s=s+f;
    }
    printf("sum = %.5lf\n", s);
    return 0;
}

题目7-01 应缴电费

春节前后,电费大增。查询之后得知收费标准如下:
月用电量在230千瓦时及以下部分按每千瓦时0.4983元收费;
月用电量在231~420千瓦时的部分按每千瓦时0.5483元收费;
月用电量在421千瓦时及以上部分按每千瓦时0.7983元收费。
请根据月用电量(单位:千瓦时),按收费标准计算应缴的电费(单位:元)。
输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。对于每组测试,输入一个整数n(0≤n≤10000),表示月用电量。
输出格式:
对于每组测试,输出一行,包含一个实数,表示应缴的电费。结果保留2位小数。
输入样例:
2
270
416
输出样例:
136.54
216.59

很不好意思,最近哥们遇到了贵人,疏于更新,希望大家谅解。今天我准备完善好第三章节的测试题详解内容----2023.3.12.23:55

#include<stdio.h>
int main()
{
int t,i;
scanf("%d",&t);//首先我们输入要测试数据的组数t
int e[t];//要测试t组数据,而每组数据只有一个数据月用电量,我们不如建立一个一维数组。
double s;//为了准确输出用电费用,我们定义费用s为实数类型
for(i=1;i<=t;i++){
    scanf("%d",&e[i-1]);//这里我们做一个for循环以便将各组数据传入数组
}
for(i=1;i<=t;i++){//这里我们开始对要测试的数据通过数组进行遍历
    if(e[i-1]<=230){//这里我们做一些条件判断来进行电量费用s的赋值
        s=e[i-1]*0.4983;
    }else if(e[i-1]<=420){
        s=230*0.4983+(e[i-1]-230)*0.5483;
    }else{
        s=230*0.4983+190*0.5483+(e[i-1]-420)*0.7983;
    }
    printf("%.2f\n",s);//这里我们保留两位小数,每组输出占据一行,打印一个回车
}
return 0;
}

题目 7-02 C程序设计实验2-2:输入今天判断后天为星期几

本题目要求输入今天星期数,进而判断后天为星期几。如果今天是星期三,后天就是星期五;如果今天是星期六,后天就是星期一。我们用数字1到7对应星期一到星期日,给定某一天,请你输出那天的“后天”是星期几。如果输入数据不符合要求,输出“Invalid Input!”。
输入格式:
输入第一行给出一个正整数D(1 ≤ D ≤ 7),代表星期里的某一天。
输出格式:
在一行中输出D天的后天是星期几。
输入样例:
1
输出样例:
3
输入样例:
-1
输出样例:
Invalid Input!
#include<stdio.h>
int main()
{
    int d,s;//这里我们定义今天的星期数和后天的星期数
    scanf("%d",&d);//这里输出今天的星期数
    if(d>=1 && d<=5){//这里因为情况比较少,我们用几个if语句即可解决
        s=d+2;
    }else if(d==6){
        s=1;
    }else if(d==7){
        s=2;
    }else{
        s=0;//值得考虑的是,当输入星期数不合法时我们可以选择赋给它一个值,作为不合法的标志。
    }
    if(s==0){
        printf("Invalid Input!\n");//这里通过s值先判断其合不合法
    }else{
        printf("%d\n",s);
    }
    return 0;
}

题目 7-03谁能进图书馆

为了保障安静的阅读环境,有些公共图书馆对儿童入馆做出了限制。例如“12 岁以下儿童禁止入馆,除非有 18 岁以上(包括 18 岁)的成人陪同”。现在有两位小/大朋友跑来问你,他们能不能进去?请你写个程序自动给他们一个回复。
输入格式:
输入在一行中给出 4 个整数:
禁入年龄线 陪同年龄线 询问者1的年龄 询问者2的年龄
这里的禁入年龄线是指严格小于该年龄的儿童禁止入馆;陪同年龄线是指大于等于该年龄的人士可以陪同儿童入馆。默认两个询问者的编号依次分别为 1 和 2;年龄和年龄线都是 [1, 200] 区间内的整数,并且保证 陪同年龄线 严格大于 禁入年龄线。
输出格式:
在一行中输出对两位询问者的回答,如果可以进就输出 年龄-Y,否则输出 年龄-N,中间空 1 格,行首尾不得有多余空格。
在第二行根据两个询问者的情况输出一句话:
如果两个人必须一起进,则输出 qing X zhao gu hao Y,其中 X 是陪同人的编号, Y 是小孩子的编号;
如果两个人都可以进但不是必须一起的,则输出 huan ying ru guan;
如果两个人都进不去,则输出 zhang da zai lai ba;
如果一个人能进一个不能,则输出 X: huan ying ru guan,其中 X 是可以入馆的那个人的编号。
输入样例 1:
12 18 18 8
输出样例 1:
18-Y 8-Y
qing 1 zhao gu hao 2
输入样例 2:
12 18 10 15
输出样例 2:
10-N 15-Y
2: huan ying ru guan
#include<stdio.h>
int main()
{
int ban,com,x,y;
scanf("%d %d %d %d",&ban,&com,&x,&y);//这里我们按照题干要求输入数据,数据间用空格隔开
if(x<ban && y<ban){//这里我选择用最笨的方法先依次考虑x的范围,对应y的范围的情况,
//分类进行讨论,也能尽可能避免漏掉一些情况
    printf("%d-N %d-N\nzhang da zai lai ba",x,y);
}if(x<ban && y>=com){
    printf("%d-Y %d-Y\nqing 2 zhao gu hao 1",x,y);
}if(x<ban && (y>=ban && y<com)){
    printf("%d-N %d-Y\n2: huan ying ru guan",x,y);
}if((x>=ban && x<com) && y<ban){
    printf("%d-Y %d-N\n1: huan ying ru guan",x,y);
}if((x>=ban && x<com) && y>=ban){
    printf("%d-Y %d-Y\nhuan ying ru guan",x,y);
}if(x>=com && y<ban){
    printf("%d-Y %d-Y\nqing 1 zhao gu hao 2",x,y);
}if(x>=com && y>=ban){
    printf("%d-Y %d-Y\nhuan ying ru guan",x,y);
}
    return 0;
}

题目 7-04 最大公约数

求两个正整数m,n的最大公约数(Greatest Common Divisor,简称GCD)。
输入格式:
首先输入一个正整数 T,表示测试数据的组数,然后是T组测试数据。每组测试输入2个整数 m, n(0< m, n<109)。
输出格式:
对于每组测试,输出 mn的最大公约数。
输入样例:
2
63 36
20 15
输出样例:
9
5
提示:
为避免超时,宜用高效的算法,例如欧几里德算法(辗转相除法)。
#include<stdio.h>
int main()
{
    int t,i,j;
    scanf("%d",&t);
    int num[t][2];//这里也是多组数据,但每组数据又有不止一个数据,
//所以我想到了用二维数组来实现。
    for(i=1;i<=t;i++){//先遍历各组数据
        for(j=1;j<=2;j++){//遍历对应到某一组的各个数据来输出
            scanf("%d",&num[i-1][j-1]);
        }
    }
    for(i=1;i<=t;i++){//这里我们的操作是为了保证每组数据的第一个数要大于第二个数
//便于后续我们进行辗转相除法
        if(num[i-1][0]<num[i-1][1]){
            int s;//这里我们在定义一下变量用来保存数据,再做下面的操作实现两个数的交换
            s=num[i-1][0];
            num[i-1][0]=num[i-1][1];
            num[i-1][1]=s;
        }
        while(num[i-1][0]%num[i-1][1]!=0){//这里我们进行辗转相除法的运作
//将前一个除数作为被除数,将前一个余数作为除数,直至被除数除以除数余零为止,
//最后一个除数就是两者的最大公约数
            int x;
            x=num[i-1][1];
            num[i-1][1]=num[i-1][0]%num[i-1][1];
            num[i-1][0]=x;
        }
        printf("%d\n",num[i-1][1]);
    }
    return 0;
}

题目 7-05 输出正整数[a,b]间符合条件的数

编写程序,输入正整数a和b,输出[a,b]区间中能被3或7整除的数,不限a和b的大小关系。
输入格式:
在一行内输入a,b值。
输出格式:
在一行内连续输出符合条件的数,每个数后跟一个空格以示间隔。
输入样例1:
10 20
输出样例1:
12 14 15 18
输入样例2:
20 10
输出样例2:
12 14 15 18
#include<stdio.h>
int main()
{
    int a,b,i;
    scanf("%d %d",&a,&b);
//这里为了保证区间的合理性,我们要保证a<b
    if(a>b){//如果a>b,我们做一个简单的交换
        int c;
        c=a;
        a=b;
        b=c;
    }
    for(i=a;i<=b;i++){
        if(i%3==0 || i%7==0){//这里判断数字是否是3的倍数或者7的倍数
            printf("%d ",i);
        }
    }
    return 0;
}

题目 7-06输入一行字符,加密后输出(凯撒加密)

编程实现对键盘输入的一行英文句子进行加密。用加密方法为,当内容为英文字母时其在26字母中的其后第三个字母代替该字母,字母x,y,z分别以a,b,c代替,字母X,Y,Z分别以A,B,C代替。若为其它字符则不变。
若为其它字符则不变。
输入格式:
输入一行英文句子
输出格式:
输出加密后的句子
输入样例1:
在这里给出一组输入。例如:
This is a test string.
输出样例1:
在这里给出相应的输出。例如:
Wklv lv d whvw vwulqj.
输入样例2:
在这里给出一组输入。例如:
ABCabc xyzXYZ&123
输出样例2:
在这里给出相应的输出。例如:
DEFdef abcABC&123
#include <stdio.h>
int main()
{
 char p;//我们首先定义一个字符变量
 while((p=getchar())!='\n')//注意到题干要求输入一行含英文字母的句子,
//也就是说当我们手动换行或者行满自动换行为输入结束
//这里我们巧用了getchar()函数输入字符的特性
/*如果输入多个数据而不回车,它不会自动执行,而之后再执行getchar时它会依次读入原输入的数据*/
//这为我们能直接输入一句话提供了便利
 {
//我们用if语句做一个简单的判断
  if(p>='A' && p<='W' || p>='a' && p<='w'){
      p+=3;
  }else if(p>='X' && p<='Z' || p>='x' && p<='z'){
      p=(p+3)-26;
  }
    printf("%c",p);
 }
 printf("\n");//这里结尾我们打印回车,保证输出留在上一行
 return 0;
}

题目 7-07 C程序设计教程与实训-循环结构-求π的近似值。

用下面的公式求π的近似值。
输入格式:
输入一个整数n。
输出格式:
输出用公式求得的π的近似值,小数点后保留7位。
输入样例:
10000
输出样例:
3.1415141
#include<stdio.h>
int main()
{
    int n,i;
    scanf("%d",&n);
    double bpai=1.0;//这里我们定义bpai为实数,来表示pai的一半,初始值令为1
    for(i=1;i<=n;i++){
        bpai*=4*i*i/((2*i-1)*(2*i+1)*1.0);//这里我们每次乘等于对应的单项,
//得到各个单项的乘积
    }
    printf("%.7f",bpai*2);//最后输出我们保留七位小数,输出pai
    return 0;
}

题目 7-08 输出a行b列字符阵列图。

本题目要求读入a和b,然后输出a行b列字符阵列图。
输入格式:
在一行中给出整数a和b。
输出格式:
输出a行b列规律图案。
输入样例:
3 4
输出样例:
ABCD
BCDE
CDEF
输入样例:
4 5
输出样例:
ABCDE
BCDEF
CDEFG
DEFGH
#include<stdio.h>
int main(){
    int a,b,i,j;
    scanf("%d %d",&a,&b);
    for(i='A';i-'A'+1<=a;i++){//先从行开始遍历进行输出,这里注意i的初始值为‘A’
        for(j=i;j-i+1<=b;j++){
            putchar(j);//对于某行的列数进行遍历来输出
//这里注意putchar的用法,对应j的ASCII码值会输出相应的字母字符
        }
        printf("\n");//对于每一行的结束我们打印回车来换行
    }
    return 0;
}

题目 7-09 统计字母出现频率

输入一段文字(以回车结束),统计其中每个字母出现的频率。
输入格式
一段文字(以回车结束)
输出格式
统计结果(包括次数和百分比,并显示条状图,参见输出样例)
输入样例1
This is a pen. That is a pencil.
输出样例1
A: 3 13.0% *************
C: 1 4.3% ****
E: 2 8.7% *********
H: 2 8.7% *********
I: 4 17.4% *****************
L: 1 4.3% ****
N: 2 8.7% *********
P: 2 8.7% *********
S: 3 13.0% *************
T: 3 13.0% *************
输入样例2
3 + 4 = 7
输出样例2
None
#include<stdio.h>
int main()
{
    int num[26]={0},i,x=0;
//这里我们定义了一个长度为26的数组,目的是存放26个字母对应出现的个数,
//而且要将数组的初始值定义为0,这里num[26]={0}我们只对数组的第一个数据做初始化为0,
//没有初始化的数据计算机会自动初始化为0
//我们还可以将数组的下标分别对应到每个字母
    char p;//这里我们定义一个字符常量为下文的输入做准备
    while((p=getchar())!='\n'){//这里我们同样利用getchar函数的特性输入一段字符
//读者可参考7-06题的思路
/*这里我们检索输入的一段字符是否出现26个字母,
若出现对应的大小写字母,则将该字母对应数组的数据加加*/
/*而这里的x有两个作用,一来可以计算输入字符段落中字母出现的总数
二来还能作为输出路径的判断条件*/
        if(p>='a' && p<='z'){
            num[p-'a']++;
            x++;
        }
        if(p>='A' && p<='Z'){
            num[p-'A']++;
            x++;
        }
    }
    if(x==0){
        printf("None");
    }else{
//下面的这个for循环是我们为了输出相应个数的星号而进行四舍五入的判断
        for(i=1;i<=26;i++){
            double s=num[i-1]/(x*1.0)*100;
            int y;
            y=(int)s;
            if((s-y)>=0.5){
                y++;
            }
            if(num[i-1]>0){
                printf("%c:%4d%6.1f%% ",('A'+i-1),num[i-1],s);
//特别注意这里我们用%c输入('A'+i-1)---ASCII码值对应的字母,
//这里我们还用了输出宽度的设置,保留小数位数的设置,
//读者可自行参考第一二单元测验选择题目2-16讲述的输出宽度的规则。
                int j;
                for(j=1;j<=y;j++){//这里我们遍历对应字母,输出相应个数的*
                    printf("*");
                }
                    printf("\n");
            }
        }
    }
    return 0;
}

题目 7-10 素因数分解

对于给定的正整数 n,输出 n的素因数的乘式。
输入格式:
输入一个正整数 n,要求1< n≤216−1。
输出格式:
输出 n的素因数的乘式,要求这些素因数呈非递减排列。
输入样例1:
102
输出样例1:
2*3*1
输入样例2:
980
输出样例2:
2*2*5*7*7
#include<stdio.h>
#include<math.h>//这里我们引用库函数为了使用开平方sqrt函数
int isprime(int x)//这里我们构建一个函数来判断一个数是否是素数
{
    int i=2;
    int door=1;//为了使返回值统一成一个变量,我们定义一个变量door
//当door==0时x不是素数,当door==1时x是素数
    for(i=2;i<=sqrt(x);i++){
//这里还是涉及判断素数的数学知识,sqrt(x)的目的是为了减少循环次数
        if(x%i==0){
            door=0;
        }
    }
    return door;//返回值令为door,以便直接拿函数isprime的返回值作为判断条件
}
int main()
{
    int n,i;
    scanf("%d",&n);
    for(i=2;i<=n;i++){//因为1不是素数,这里从2开始遍历
        if(isprime(i) && n%i==0){//条件是i是素数,且i是n的因数
            if(i==n){//当i==n时显然到了输出最后一个因子的时候
                printf("%d",i);
                break;//这时直接跳出循环即可
            }else{
                printf("%d*",i);
                n/=i;//每次循环之后n相应地除掉已经输出的因子
                i=1;
//令i=1,该轮循环结束i++,重新得到i=2开始的循环来查找下一个素因数
            }
        }
    }
    return 0;
}

题目 7-11 十进制整数转换成R进制数

这是一个编程题模板。
编程实现将任意的十进制整数N转换成R进制数(R在2-16之间)。N<0则直接退出。
输入格式:
一行中输入两个数分别是N与R,两者之间以空格隔开。
输出格式:
将转换后的R进行数。
输入样例1:
在这里给出一组输入。例如:
23 2
输出样例1:
在这里给出相应的输出。例如:
10111
输入样例2:
在这里给出一组输入。例如:
23 8
输出样例2:
在这里给出相应的输出。例如:
27
输入样例3:
在这里给出一组输入。例如:
123 16
输出样例3:
在这里给出相应的输出。例如:
7B
#include<stdio.h>
int main()
{
    int n,r;//这里我们要先明白进制转换的基本办法,
//就是将原来的数字不断除以进制数得到一系列余数
    int num[100],i=1;//我们这里申请一个数组用来保存得到的一系列余数
    scanf("%d %d",&n,&r);
    if(n==0){//考虑到特殊值0进制转换还是0,我们直接输出即可
        printf("0");
    }else{
        while(n!=0){//这里对原数字n做循环得到每次除以进制数后的余数
        num[i-1]=n%r;
        n/=r;
        i++;
    }
    int j;
    for(j=i-1;j>0;j--){//考虑到如果进制数在10以内直接输出相应数字即可
//若进制数大于十,往后的数字依次用ABCD...来表示,
//通过对应ascii码值与取余后得到数字间的关系准确输出字母,
//ch=num[j-1]-9+'A'-1这个即是它们的关系
        if(num[j-1]<=9){
            printf("%d",num[j-1]);
        }else{
            int ch;
            ch=num[j-1]-9+'A'-1;
            printf("%c",ch);
        }
    }
    }
    return 0;
}

题目 7-12 可逆素数

素数是指除了1和本身之外再没有因子的正整数。1不是素数,2是素数,13也是素数。
可逆素数是指: 一个素数将其各位数字的顺序倒过来构成的反序数也是素数。 比如17是素数,倒过来的71也是素数,那么17是可逆素数;2也是可逆素数。
请计算某个区间内的可逆素数的个数。
从键盘输入2个正整数(这里保证区间的合理性,读者无需考虑),输出该区间内的可逆素数的个数。
输入样例:
1001 9999
输出样例:
204
#include<stdio.h>
#include<math.h>
int isprime(int x)//这里我们构造一个函数来判断一个数是不是素数
//如果返回值为0,则不是,返回值为1则是
{
int i=2,door=1;
if(x==0 || x==1){
    door=0;
}
for(i=2;i<=sqrt(x);i++){//这里为了减少循环次数我们只需循环到sqrt(x),
//上面涉及到的知识是初中数学,读者可自行查阅
if(x%i==0){
door=0;
}
}
return door;
}
int Ni(int x)//这里我们构建一个函数来得到一个数的逆序数
{
int result=0;
while(1){
    int j=x%10;
    result=result*10+j;
    x=x/10;
    if(x==0){
break;
    } 
    }
    return result;
}
int main()
{//这主函数里,我们可以把已构建好的函数直接拿来使用
int m,n;
scanf("%d %d",&m,&n);
int cnt=0,i;//我们定义cnt来表示可逆素数的个数
for(i=m;i<=n;i++){
if(isprime(i) && isprime(Ni(i))){//这里判断如果数字i和它的逆序数均是素数
//则可逆素数个数+1
cnt++;
}
}
printf("%d",cnt);
return 0;
}

第四章 数组

题目5-1 一维数组元素倒置

请完善程序,实现以下功能:将具有n个元素的一维数组的内容前后倒置。
输入样例1:
10
11 12 13 14 15 16 17 18 19 20
输出样例1:
20 19 18 17 16 15 14 13 12 11
输入样例2:
5
12 32 34 45 65
输出样例2:
65 45 34 32 12
#include <stdio.h>
int main(void)
{
    int n,i,j,t;
    scanf("%d",&n);//输入整数的总个数n
    int a[n];
    for(i=0;i<=n-1;i++)//输入n个整数(用空格分隔)
        scanf("%d", &a[i]);
    for(i=0,j=n-1;i<=(n-1)/2;i++,j--){//这里注意i<=(n-1)/2为循环的条件
//如果i<(n-1)为循环条件相当于做了一整轮对换仍然是原来的序列,所以我们只需要做一半的对换即可
//至于数字的个数是奇数还是偶数显然无影响,奇数最中间那个数是不用换的。 
//下面是数字交换的常规做法,采用变量t先保存一个数,然后做交换
        t=a[i];   
        a[i]=a[j];   
        a[j]=t;
    }
    for(i=0;i<n;i++)
        printf("%d ",a[i]); 
    return 0;
}

题目 5-2 二分查找

有15个已经排好序的数存放在一个数组中,输入一个数,要求用折半查找法找出该数是数组中第几个元素的值。

如果该数不在数组中,则输出无此数。请填空。

变量说明:top,bott为查找区间两端点的下标;loca为查找成功与否的开关变量。
#include <stdio.h>
int main(void)
{
//这里读者可参考小郭的另一篇帖子NWAFU-OJ练习题1001二分查找的详解
    int N, number, top, bott, min, loca;
    int a[15] = { -3, -1, 0, 1, 2, 4, 6, 7, 8, 9, 12, 19, 21, 23, 50};
    N = 15;
    scanf("%d", &number);
    loca = 0; top = 0; bott = N - 1;
//这里的loca是我们最终要找数字number在数组中的下标
//top,bott是我们不断缩小查找范围区间的左右端点
    if ((number < a[0]) || (number > a[N - 1]))
//这里我们先判断要找的数字是否在该序列范围内若不在直接一票否决
        loca = -1;
    while ((loca == 0) && (top <= bott)){
//这里做了一个while循环,loca的初始值为零,而我们查到数字number的最后一步才将下标赋给loca
//所以loca值不为零我们就要结束循环
//另外,如果我们不断缩小范围直至top==bott时还没有找到数字,
//继续做到下一步,要么top加了1,要么要么bott-1,结果就是top>bott,循环停止
        min = (top+bott)/2;
        if (number == a[min]) {
            loca = min;
            printf("The serial number is %d\n", loca + 1);
            break;
        } else if(number < a[min])
    bott = min - 1;
        else top=min+1;
    }
    if (loca==-1 || top>bott)//没找到数字的情况就是一、没在范围内:loca==-1
//二、循环结束仍然没有找到:top>bott
        printf("%d isn't in table\n", number);
    return 0;
}

题目 5-3 选择法排序

选择法排序:本题要求将给定的 n个整数从小到大排序后输出。输出时相邻数字中间用一个空格分开,行末不得有多余空格。
#include <stdio.h>
# define MAXN 10//这里我们定义宏,MAXN表示数组个数n的最大界限
int main()
{
    int i, index, k, n, temp;
    int a[MAXN];
    scanf("%d", &n);//输入
    for(i = 0; i < n; i++){
        scanf("%d", &a[i]);
    }//输入结束
//这里我们大概阐述一下选择排序的思想,选择排序实际上是先找出第一轮的最值(不妨就最小值)
//然后将第一轮的最小值放在数组的第一个位置,但实际上我们不能只是放,而要进行交换来保存原有数据
//然后去除第一个数据我们在剩下的序列中再找到最小的数据放在第二个位置,
//也就是放在第一轮最小数存放位置的后面,依次做下去,我们就会得到一个排好序的数字序列
    for(k = 0; k < n-1; k++){
        index = k;  
        for(i=k;i<=n-1;i++){
//这里我们做一个从上一轮最小值后面的序列开始的循环,继续找到本轮最小值
//记录本轮最小值的下标index方便后面的交换
            if(a[i]<a[index]){
                index = i;  
            }    
        }  
        temp=a[index];
        a[index]=a[k];
        a[k]=temp;
    }
   for(i = 0; i < n; i++) {
        if(i==0){
            printf("%d", a[i]);
        }else{
            printf(" %d", a[i]);
        }
    }
    printf("\n");
    return 0;
}

题目 5-4 简单的插入法排序

简化的插入法排序。以下程序段A和B的功能都是:将一个给定的整数 x插到原本按升序排列的整数序列中,使结果序列仍然按升序排列。

程序A

#include<stdio.h>
//实际在作该代码的时候,直接默认了数字x不会放在在原序列的首尾位置
int main()
{
    int n;//输入
    scanf("%d",&n);
    int i=1,a[n+1];
    for(i=1;i<=n;i++){
    scanf("%d",&a[i-1]);
    }
    int x,j;
    scanf("%d",&x);//输入结束
    for(i=0;i<n;i++){//这里做循环,我们先找到数字x在该组序列中应放置位置的下标
        if(a[i+1]>=x && a[i]<x){
        break;
        }
    }
    for(j=n-1;j>i;j--){//这里因为我们申请数组变量的时候多申请了一位
//我们可以从最后一个数字开始挪动数组,而不会覆盖原有数字
        a[j+1] = a[j];
    }
    a[i+1]=x;//将x放在它应放的位置
    n++;
    for(i=1;i<=n;i++){
    printf("%d ",a[i-1]);
}
return 0;
}

程序B (实际上和程序A的原理是一样的,只不过程序B没有直接寻找数字x要存放的位置,而是边寻找,边移动数据)

#include<stdio.h>
int main()
{
    int n;
    scanf("%d",&n);
    int i=1,a[n+1];
        for(i=1;i<=n;i++){
        scanf("%d",&a[i-1]);
    }
    int x,j;
    scanf("%d",&x);
        for (i = n-1; i >= 0; i--){
            if(x < a[i]){  
                a[i+1]=a[i];
            }else{
                break;
            }
        }
        a[i+1]=x;
        n++;
        for(i=1;i<=n;i++){
        printf("%d ",a[i-1]);
    }
    return 0;
}

题目 5-5 字符串复制

字符串复制。
以下程序段的功能是:将字符串 str1的内容复制到字符串 str2。
int i;
char str1[81], str2[81];
i = 0;
//字符串的结尾都以'\0'结尾
while (str1[i]!='\0'){//判断条件当字符串未到结尾时,作复制
    str2[i]=str1[i];
    i++;
}
str2[i]='\0';//将复制后的字符串结尾的'\0'补上

题目 5-6 删除字符串中的空格(使用2个数组)

删除字符串中的空格(使用2个数组)。
以下程序段的功能是:滤去字符串 str1中的所有空格,生成一个新的字符串 str2。
int i, j;
char str1[81], str2[81];
i = j = 0;
while (str1[i] != '\0'){//字符串以'\0'结尾
    if(str1[i]!=' '){ //如果字符串中的字符不是空格就记录到字符数组中     
        str2[j]=str1[i];
        j++;
    }
    i++;
}
str2[j]='\0';//为字符数组的结尾补上'\0'

题目 5-7 大小写字母转换(使用1个数组)

大小写字母转换(使用1个数组)。
以下程序段的功能是:将字符串 str中的小写字母全部转换成大写字母,大写字母全部转换成小写字母,其他字符不变。
int i;
char str[81];
i = 0;
while(str[i]!='\0'){
    if (str[i] >= 'a' && str[i] <= 'z'){//判断如果对应字符为小写,则转换成大写    
        str[i]+=('A'-'a');
    }
    else if(str[i] >= 'A' && str[i] <= 'Z'){//判断如果对应字符为大写,则转换成小写     
        str[i]+=('a'-'A');
    }
    i++;
}

题目 5-8 求矩阵各列元素之和

求一个给定的 m× n矩阵各列元素之和。
输入格式:
输入第一行给出两个正整数 mn(1≤ m, n≤6)。随后 m行,每行给出 n个整数,其间以空格分隔。
输出格式:
每行输出对应矩阵列元素之和。
输入样例:
3 2
6 3
1 -8
3 12
输出样例:
10
7
#include <stdio.h>
#define MAXM 6
#define MAXN 6
int main()
{
    int i, j, m, n, sum;
    int a[MAXM][MAXN];
    scanf("%d %d", &m, &n);//输入
    for (i=0;i<m;i++){
        for(j=0;j<n;j++){
            scanf("%d",&a[i][j]);
        }
    }//输入结束

    for(j=0;j<n;j++){//先对列循环   
        sum=0;//求每轮列和之后要将sum清零
        for(i=0;i<m;i++){//在每个列内对每个行循环,做加和
            sum += a[i][j];
        }
        printf("%d\n", sum);
    }
    return 0;
}

题目 5-9 矩阵a的主对角线上的元素之和

下面程序可求出矩阵a的主对角线上的元素(行标和列标相等的元素)之和,请填空使程序完整。
#include <stdio.h>
int main() {
  int a[3][3]={1,3,5,7,9,11,13,15,17},sum=0,i,j;
  for(i=0;i<3;i++)
    for(j=0;j<3;j++)
      if(i==j)//如果是主对角线
//当行标和列标相等时为矩阵的主对角线上的数字
        sum=sum+a[i][j];
  printf("sum=%d",sum);
  return 0;
}

题目 5-10 判断方阵对称

输入一个正整数 n (1≤n≤10)和n 阶方阵a的元素,如果方阵a中的所有元素都沿主对角线对称,输出“Yes”, 否则,输出“No”。主对角线为从矩阵的左上角至右下角的连线,方阵a中的所有元素都沿主对角线对称指对所有i, k,a[i][k]和a[k][i]相等。输入输出示例如下:
输入:
3
1 2 3
4 5 6
7 8 9
输出:
No
#include <stdio.h>
int main(void)    
{    
    int found, i, k, n;
    int a[10][10];
    scanf ("%d", &n);//输入
    for(i=0;i<n;i++)    
        for(k=0;k<n;k++)
            scanf("%d",&a[i][k]);//输入结束
    found=1;
    for (i=0;i<n;i++){    
        for (k = 0; k < i; k++){
//这里k<i为判断条件保证是下三角或者上三角中的数字,避免重复判断
            if (a[i][k]!=a[k][i]){                  
                found=0;//这里found相当于一个开关如果出现不对称就赋给它0          
                break;
            }
        }
        if (n==1){
            break;//如果n=1的时候一定是对称方阵,跳转到该语句直接结束循环就可
        }
    }
    if(found!=0){
        printf("Yes\n");
    }else{
        printf("No\n");
    }  
    return 0;
}

题目 5-11 输出杨辉三角形的前n行

请补全代码,输入如下图所示的杨辉三角形前n行,n由用户从键盘输入(n<=20),请不要填写多余的空格。
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
#include <stdio.h>
#define N 20
void CalculateYH(int a[][N],int n); 
void PrintYH(int a[][N],int n);
int main()
{
    int a[N][N]={0},n;
    scanf("%d",&n);
    CalculateYH(a,n);
    PrintYH(a,n);
    return 0;
}
//计算杨辉三角形前n行元素的值 
void CalculateYH(int a[][N],int n)
{
    int i,j;
    for(i=0;i<n;i++){//先将每一行要输出的第一个值和最后一个值赋为1
        a[i][0]=1;
        a[i][i]=1;
    } 
    for(i=2;i<n;i++){
        for(j=1;j<=i-1;j++){
            a[i][j]=a[i-1][j]+a[i-1][j-1];
        }
    }
}
//输入杨辉三角形前n行元素的值
void PrintYH(int a[][N],int n)
{
    int i,j;
    for(i=0;i<n;i++){
        for(j=0;j<=i;j++){
            printf("%4d",a[i][j]);    
        }
        printf("\n");    
    }
}

题目 7-03 交换最小值和最大值

本题要求编写程序,先将输入的一系列整数中的最小值与第一个数交换,然后将最大值与最后一个数交换,最后输出交换后的序列。
注意:题目保证最大和最小值都是唯一的。
输入格式:
输入在第一行中给出一个正整数N(≤10),第二行给出N个整数,数字间以空格分隔。
输出格式:
在一行中顺序输出交换后的序列,每个整数后跟一个空格。
输入样例:
5
8 2 5 1 4
输出样例:
1 2 5 4 8
#include<stdio.h>
int main()
{
int n;
scanf("%d",&n);
int a[n],i;
for(i=0;i<n;i++){
scanf("%d",&a[i]);
}//输入结束
int reserve=a[0],indexmin=0,min=a[0];
for(i=0;i<n-1;i++){
//我们采用遍历不断更迭最小值,并记录最后最小值对应的下标
if(a[i+1]<min){
min=a[i+1];
indexmin=i+1;
}
}
//循环结束我们将最小值与第一个值交换
a[0]=a[indexmin];
a[indexmin]=reserve;
int indexmax=0,max=a[0];
reserve=a[n-1];
//接下来我们遍历不断更迭最大值,并记录最大值的下标
for(i=0;i<n;i++){
if(a[i]>max){
max=a[i];
indexmax=i;
}
}
//循环结束后交换
a[n-1]=a[indexmax];
a[indexmax]=reserve;
//打印结果
for(i=0;i<n;i++){
printf("%d ",a[i]);
}
return 0;
 } 

题目 7-09 查找指定字符

本题要求编写程序,从给定字符串中查找某指定的字符。
输入格式:
输入的第一行是一个待查找的字符。第二行是一个以回车结束的非空字符串(不超过80个字符)。
输出格式:
如果找到,在一行内按照格式“index = 下标”输出该字符在字符串中所对应的最大下标(下标从0开始);否则输出"Not Found"。
输入样例1:
m
programming
输出样例1:
index = 7
输入样例2:
a
1234
输出样例2:
Not Found
#include<stdio.h>
int main()
{
    char found;
    scanf("%c\n",&found);我们第一行输入一个要查找的字符found然后输入回车
    char ch[80]={0};//这里我们可以先对字符数组进行初始化
    int i=1,cnt=0;
    while(1){//这里我们输入一系列字符用while(1)来进行循环,以break跳出循环
        scanf("%c",&ch[i-1]);
        if(ch[i-1]!='\n'){
            i++;
        }else{
            cnt=i;//跳出循环时记录输入字符的总数,这里cnt实际上字符总数加1
            break;
        }
    }
    int index,door=0;//我们以door为开关,如果没找到字符found,door的值仍为0
    for(i=1;i<cnt;i++){//这里我们遍历字符数组并记录要查找字母所在的下标
        if(ch[i-1]==found){
            door=1;
            index=i-1;
        }
    }
    if(door==0){//这里我们以door作为条件来判断并选择输出
        printf("Not Found");
    }else{
        printf("index = %d",index);
    }
    return 0;
}

题目 7-02 数组元素循环右移

一个数组 A中存有 N(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移 M(≥0)个位置,即将 A中的数据由( A0 A1⋯ AN−1)变换为( ANMAN−1 A0 A1⋯ ANM−1)(最后 M个数循环移至最前面的 M个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?
输入格式:
每个输入包含一个测试用例,第1行输入 N(1≤ N≤100)和 M(≥0);第2行输入 N个整数,之间用空格分隔。
输出格式:
在一行中输出循环右移 M位以后的整数序列,之间用空格分隔,序列结尾不能有多余空格。
输入样例:
6 2
1 2 3 4 5 6
输出样例:
5 6 1 2 3 4
#include<stdio.h>
int main()
{
    int n,m;
    scanf("%d %d",&n,&m);
    int num[n],i;
    for(i=1;i<=n;i++){
        scanf("%d",&num[i-1]);
    }
    int s=num[0],first=num[n-1],reserve,j;
    for(j=1;j<=m;j++){//每循环依次数据都向右移动一位,我们循环m次即可
        s=num[0];
        first=num[n-1];//这里我们保存最后一个数字,然后将除最后一个数外数组中所有数据向右移动一位
//读者可自行思考,实际上没必要引入多余的变量,只需要保存最后一个数即可
//这里是我最开始草稿纸上的想法,引入了一些多余的变量
        for(i=1;i<n;i++){
            if(i%2==1){
                reserve=num[i];
                num[i]=s;
            }else{
                s=num[i];
                num[i]=reserve;
            }
        }
        num[0]=first;
    }
    for(i=1;i<n;i++){
        printf("%d ",num[i-1]);
    }
    if(i==n){
        printf("%d",num[i-1]);
    }
    return 0;
}

题目 7-07求n个整数的平均值与中位数

从键盘接收一个整数n,假定用户输入的n一定是满足 3 <= n <= 100。接下来,从键盘 接收n个整数存入数组。用户输入的整数,大小是 杂乱无序的。
计算这n个数的平均值和中位数。中位数就是 数组元素升序排列后,最中间的一个数(奇数个数据),或中间两个元素平均值(偶数个元素)。
输入格式:
第一个整数4告诉计算机要输入4个数字。第二行输入这四个数字,数字之间用空格分开。
4
3 1 2 9
输出格式:
平均值保留 2位小数,中位数保留 1位小数。两项信息之间用纯英文逗号隔开,整个输出信息中不含空格。
mean=3.75,median=2.5
输入样例1:
输入 奇数个数据,中位数就是排序后,最中间的数字6。
5
6 2 4 10 18
输出样例1:
注意分别是2位小数和1位小数。
mean=8.00,median=6.0
输入样例2:
输入 偶数个数据,中位数就是排序后, 中间两个数2和3的平均值。
4
3 1 2 9
输出样例2:
mean=3.75,median=2.5
#include<stdio.h>
int main()
{
    int n;
    scanf("%d",&n);//输入
    int i,num[n];
    for(i=1;i<=n;i++){
        scanf("%d",&num[i-1]);
    }//输入结束
    int j;
    for(j=n;j>=2;j--){//这里我们做了一个冒泡排序
        for(i=1;i<j;i++){
            if(num[i]<num[i-1]){
                int x;
                x=num[i];
                num[i]=num[i-1];
                num[i-1]=x;
            }
        }
    }
    double mid,average;
    if(n%2==1){//排好序的数我们用来求出中位数
        mid=num[(n+1)/2-1];
    }else{
        mid=(num[n/2-1]+num[n/2])/2.0;
    }
    int sum=0;
    for(i=1;i<=n;i++){//求数字的和
        sum+=num[i-1];
    }
    average=sum/(n*1.0);//求出平均数,注意int类型与实数之间运算的细节
    printf("mean=%.2f,median=%.1f",average,mid);
    return 0;
}

题目 7-06 找出不是两个数组共有的元素

给定两个整型数组,本题要求找出不是两者共有的元素。
输入格式:
输入分别在两行中给出两个整型数组,每行先给出正整数 N(≤20),随后是 N个整数,其间以空格分隔。
输出格式:
在一行中按照数字给出的顺序输出不是两数组共有的元素,数字间以空格分隔,但行末不得有多余的空格。题目保证至少存在一个这样的数字。同一数字不重复输出。
输入样例:
10 3 -5 2 8 0 3 5 -15 9 100
11 6 4 8 2 6 -5 9 0 100 8 1
输出样例:
3 5 -15 6 4 1
#include <stdio.h>
#define N 20
int main()
{
//这里我们定义三个一维数组,我们打算把第一行输入数字(滤去重复的)剩余的放在数组a[N]里
//然后第二个数组里面放第二行输入数字 (滤去该行中重复的,还有与数组a[N]重复的)
//同时我们把第二行输入数字中与a[N]重复的数字放入c[N]中
//然后输出的时候对于a[N],如果a[N]中的数字在c[N]中也出现就不输出,如果在c[N]中不出现就输出
//对于b[N]没有与自身和a[N]重复的数字可以直接输出,c[N]只是一个参照
    int a[N] = { 0 };
    int b[N] = { 0 };
    int c[N] = { 0 };
    int i, j, t, flag = 0, flag1 = 0, n1, n2, cnt = 0, cnt1 = 0;
//这里cnt,cnt1最终记录数组中输入数字的个数并赋给相应数组
//flag,flag2作为辅助参数“开关”当作一些步骤的判断条件
//我们每次输入的数字都先存放在t里面,然后判断条件来决定是否将它放进对应的数组中
    scanf("%d", &n1);
    for (i = 0; i < n1; ++i){
        scanf("%d", &t);
        flag = 0;
        for (j = 0; j < cnt; j++){
            if (a[j] == t){
                flag = 1;
                break;
            }
        }
        if (flag == 0){
            a[cnt ++] = t;
        }
    }
    n1 = cnt;
    cnt = 0;
    scanf("%d", &n2);
    for (i = 0; i <n2; ++i){
        scanf("%d", &t);
        flag = 0;
        flag1 = 0;
        for (j = 0; j < cnt; j++){
            if (b[j] == t){
                flag = 1;
                break;
        }
    }
    for (int k  = 0; k < n1; ++k){
        if (a[k] == t){
            c[cnt1++] = t;
            flag1 = 1;
            break;
         }
    }
    if (flag == 0 && flag1 == 0)
        b[cnt ++] = t;
    }
    n2 = cnt;
    for (i = 0; i < n1; ++i){
        flag = 0;
        for (j = 0; j < cnt1; ++j){
            if (a[i] == c[j]){
            flag = 1;
            break;
        }
    }
    if (flag == 0)
        printf("%d ", a[i]);
    }
    for (i = 0; i < n2 - 1; ++i){
        printf("%d ", b[i]);
    }
    printf("%d\n", b[i]);
    return 0;
}

题目 7-10 字符串中的数字之和

程序要求能够提取输入的字符串中的数字,将数字累加,得到数字之和,如输入的字符串为"abc76wet23er1.",应该提取数字76,23,1,求和后,即76+23+1=100,要求输入的字符串最后一个字符不能为数字字符。
输入格式:
输入一个字符串,字符串长度不超过100.
输出格式:
输出字符串中的数字之和
输入样例1:
在这里给出一组输入。例如:
abc76wet23er1.
输出样例1:
在这里给出相应的输出。例如:
100
输入样例2:
在这里给出一组输入。例如:
wwq100rty23fg45k
输出样例2:
在这里给出相应的输出。例如:
168
#include<stdio.h>
#define N 100//这里宏定义常量N为100
int main()
{
    char a[N];
    int i=0,n;
    while((a[i]=getchar())!='\n'){//这里我们利用while循环读入一系列字符
//以'\n'结束输入
        i++;
    }
    n=i;
    int y=0,sum=0;
    for(i=0;i<n;i++){
//这里我们以开始遇到数字为起点
        if(a[i]<='9' && a[i]>='0'){
//如果遇到数字就进入循环作运算,求出每次遇到的数字串对应的值,累加到sum里面去
            while(a[i]<='9'&&a[i]>='0'){
                y=y*10+a[i]-'0';
                i++;
            }
            sum+=y;
        }else{
//当每次遇到的数字串收尾时将y的值重新赋为0
            y=0;
        }
    }
    printf("%d",sum);
//打印最终结果
    return 0;
} 

题目 7-05 方阵边上元素求和

n阶方阵从外到内四周 k圈上的数字之和。
输入格式:
输入数据的第一行为一个正整数 T,表示测试数据的组数。然后是T组测试数据。
每组测试数据的第一行为两个整数 nk(3≤ n≤15,1≤ k< n/2), n表示方阵的阶数, k表示方阵从外到内四周的圈数。然后输入 n行,每行 n个整数。
输出格式:
对于每组测试,输出的形式为“sum=num”,其中 num为所求的和值(结果保证小于231)。注意:引号不必输出。
输入样例:
2
3 1
9 8 7
3 4 8
7 5 6
5 2
9 2 5 7 2
2 6 7 2 7
2 8 5 1 4
9 6 8 7 7
3 7 9 3 8
输出样例:
sum=53
sum=131
#include<stdio.h>
int main(){
    int T;
    scanf("%d",&T);
    while(T--){//这里我们巧妙的使用while循环,以T--为条件,每次判断条件时使T--
//当T--的结果为0时循环结束(这里注意T--和--T的区分)
        int n,k;
        scanf("%d%d",&n,&k);//输入
        int a[15][15];
        for(int i=0;i<n;++i){
            for(int j=0;j<n;++j){
                scanf("%d",&a[i][j]);
            }
        }//输入结束
        int sum=0;
        for(int p=0;p<k;++p){//这里循环k圈
            for(int i=p;i<n-p;++i){//这里计算每一圈的首行和尾行的数字和
                sum+=a[p][i];
                sum+=a[n-1-p][i];
            }
            for(int i=p+1;i<n-1-p;++i){
//这里计算每一圈去除首行和尾行的各行的圈开始的数字和圈结束的数字
                sum+=a[i][p];
                sum+=a[i][n-1-p];
            }
        }
        printf("sum=%d\n",sum);//输出最终各圈数字和
    }
    return 0;
}

题目 7-08 矩阵A乘以B

给定两个矩阵 AB,要求你计算它们的乘积矩阵 AB。需要注意的是,只有规模匹配的矩阵才可以相乘。即若 ARa行、 Ca列, BRb行、 Cb列,则只有 CaRb相等时,两个矩阵才能相乘。
输入格式:
输入先后给出两个矩阵 AB。对于每个矩阵,首先在一行中给出其行数 R和列数 C,随后 R行,每行给出 C个整数,以1个空格分隔,且行首尾没有多余的空格。输入保证两个矩阵的 RC都是正数,并且所有整数的绝对值不超过100。
输出格式:
若输入的两个矩阵的规模是匹配的,则按照输入的格式输出乘积矩阵 AB,否则输出Error: Ca != Rb,其中Ca是 A的列数,Rb是 B的行数。
输入样例1:
2 3
1 2 3
4 5 6
3 4
7 8 9 0
-1 -2 -3 -4
5 6 7 8
输出样例1:
2 4
20 22 24 16
53 58 63 28
输入样例2:
3 2
38 26
43 -5
0 17
3 2
-11 57
99 68
81 72
输出样例2:
Error: 2 != 3
#include<stdio.h>
int main()
{
    int Ra,Ca,Rb,Cb;
    scanf("%d%d",&Ra,&Ca);//这里我们读入第一个矩阵的行数和列数
    int a[Ra][Ca],i,j;
    for(i=0;i<Ra;i++){
        for(j=0;j<Ca;j++){
            scanf("%d",&a[i][j]);//读入第一个矩阵各行各列的数据
        }
    }
    scanf("%d%d",&Rb,&Cb);//读入第二个矩阵的行数和列数
    int b[Rb][Cb];
    for(i=0;i<Rb;i++){
        for(j=0;j<Cb;j++){
            scanf("%d",&b[i][j]);//读入第二个矩阵各行各列的数据
        }
    }
    if(Ca==Rb){//判断矩阵是否可以作乘
        int c[Ra][Cb];//若矩阵可以作乘,我们不妨再定义一个数组来保存乘积后的矩阵
        printf("%d %d\n",Ra,Cb);
        for(i=0;i<Ra;i++){
            for(j=0;j<Cb;j++){
                int y=0,k=0;
//对于新矩阵的第i行第j列个元素的值即为原矩阵第i行对应元素与第j列对应元素的乘积和
                for(k=0;k<Ca;k++){
                    y+=a[i][k]*b[k][j];
                }
                c[i][j]=y;
            }
        }
        for(i=0;i<Ra;i++){//这里我们将得到的乘积矩阵输出即可
            for(j=0;j<Cb;j++){
                printf("%d",c[i][j]);
                if(j<Cb-1){
                    printf(" ");//注意每行除最后一个元素外其余元素后都要输出一个空格
                }
            }
            printf("\n");//每行输出结束后打印回车
        }
    }else{
        printf("Error: %d != %d",Ca,Rb);
//注意如果两矩阵不能作乘要输出的内容,记得输出Ca和Rb的具体值
    }
    return 0;
}

第四章 单元测验

题目 5-2 完成将输入的一个数字字符串转变为整型数值的功能

完成将输入的一个数字字符串转变为整型数值的功能
#include<stdio.h>
void main()
{
   char cstr[8];
   int ii;
   long ls;  
   gets(cstr);//这里读入一个字符串
   ls=0;
   for(ii=0;cstr[ii]!='\0';ii++)
   ls=ls*10+cstr[ii]-'0';//这里注意数字字符与数字之间的转换
   printf("%ld",ls);
}

题目 5-3 在一个字符数组中查找一个指定的字符

在一个字符数组中查找一个指定的字符,若数组中含有该字符则输出该字符在数组中第一次出现的位置(下标值)否则输出-1。
#include<stdio.h>
void main()
{
   char ch='a',cstr[50];
   int inum,ii,iflag=1;
   gets(cstr);
   inum=strlen(cstr);
   for(ii=0;ii<inum;ii++)
       if(cstr[ii]==ch){//当查找到第一个要找的字符时结束循环
//值得注意的时break;语句过后ii++便不再做了,所以需要注意这时候ii的值
           iflag=0;
           break;
   }
   if(iflag==1)
        printf("%d",-1);
   else
        printf("%d",ii);//最终要找字符第一次出现的下标应该是ii
}

题目 5-6 对10个整数按照从小到大进行排序

对10个整数按照从小到大进行排序。
#include <stdio.h>
int main()
{ 
//这个代码的做法是典型的选择排序的做法
//基本思想是先在未排序的序列中找出最小值,放在第一位,
//然后继续在剩下未排序的序列中找出最小值放在第一次找出最小值位置的后面
//依次类推,直至找出所有最小值,即可排好序
    int a[10],i,j,min,t;
    for (i=0;i<10;i++)
        scanf("%d",&a[i]);
    for(i=0;i<=9;i++){//这里对序列作遍历,以达到每个位置放的都是对应的‘最小值’ 
        min=i;这里我们先将最小值的下标min令为i  
        for(j=i+1;j<10;j++)
//然后在后面的序列遍历查找是否有更小的值,若有则更换min的值
            if(a[min]>a[j])
                min=j; 
        if(min!=i){
//一圈遍历后判断,然后作交换
            t=a[i];  
            a[i]=a[min];  
            a[min]=t;
        }
    }
    for(i=0;i<10;i++)
        printf("%d ",a[i]);
    return 0;
}

题目 7-3 判断双对称方阵

对于一个n阶方阵,请判断该方阵是否双对称,即既左右对称又上下对称。若是则输出“yes”,否则输出“no”。例如,样例中,以第2列为界则左右对称,以第2行为界则上下对称,因此输出“yes”。
输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。每组数据的第一行输入方阵的阶n(2≤n≤50),接下来输入n行,每行n个整数,表示方阵中的元素。
输出格式:
对于每组测试数据,若该方阵双对称,则输出“yes”,否则输出“no”。注意,引号不必输出。
输入样例:
2
3
1 2 1
3 5 3
1 4 1
3
1 2 1
3 5 3
1 2 1
输出样例:
no
yes
#include<stdio.h>
int main()
{
    int t;
    scanf("%d",&t);//这里我们先读入t的值
    int a[t],i;
    for(i=0;i<t;i++){
//作遍历输入t组数据并处理输出结果
        scanf("%d",&a[i]);
//我们先输入第(i+1)组矩阵的阶数
        int b[a[i]][a[i]];
//然后利用二维数组读入矩阵数据,
//这里定义的数组是在第一个for循环的块里面的,每次循环可重新更改定义
//这要求我们需要在每次进入循环都做好输出的处理
        int k,j,flag=1;
//这里我们定义变量flag作为标志为后续选择输出作准备
        for(j=0;j<a[i];j++){
//输入
            for(k=0;k<a[i];k++){
                scanf("%d",&b[j][k]);
            }
        }
        for(j=0;j<a[i];j++){
//遍历矩阵的各行各列
            if(b[j][0]!=b[j][a[i]-1]){
//判断第j行的第一个和最后一个元素是否相同
                flag=0;
                break;
            }
            if(b[0][j]!=b[a[i]-1][j]){
//判断第j列的第一个和最后一个元素是否相同
                flag=0;
                break;
            }
        }
        if(flag==1){
            printf("yes\n");
        }else{
            printf("no\n");
        }
    }
    return 0;
}

第四章 数组-拓展练习

题目 7-1 猜数字

一群人坐在一起,每人猜一个 100 以内的数,谁的数字最接近大家平均数的一半就赢。本题就要求你找出其中的赢家。
输入格式:
输入在第一行给出一个正整数N(≤104)。随后 N 行,每行给出一个玩家的名字(由不超过8个英文字母组成的字符串)和其猜的正整数(≤ 100)。
输出格式:
在一行中顺序输出:大家平均数的一半(只输出整数部分)、赢家的名字,其间以空格分隔。题目保证赢家是唯一的。
输入样例:
7
Bob 35
Amy 28
James 98
Alice 11
Jack 45
Smith 33
Chris 62
输出样例:
22 Amy
#include<stdio.h>
#include<math.h>
#define num 9
int main()
{
    int N;
    scanf("%d",&N);//这里我们读入N的值
    int a[N],i;
    int sum=0;
    char ch[N][num];
    for(i=0;i<N;i++){
        int j=0;
        scanf("\n");//值得注意的是后面我们scanf读入字符时会误读回车转义字符
//我们选择scanf读入一个回车字符来避免这个问题
        while(1){
//这里我们读入对应玩家的名字,以空格结束
            scanf("%c",&ch[i][j]);
            if(ch[i][j]==' '){
                break;
            }
            j++;
        }
        scanf("%d",&a[i]);
        sum+=a[i];//将每次读入的数据作累加求和
    }
    double x;
    x=sum/2.0/N; 
    int index=0;
    double min=fabs(a[0]-x);
//这里我们使用了绝对值函数来表示玩家所猜的数字与平均数一半的距离
    for(i=0;i<N-1;i++){
        if(min>fabs(a[i+1]-x)){
//作判断并不断更迭最小距离和对应下标
            index=i+1;
            min=fabs(a[i+1]-x);
        }
    }
    int y=(int)x;
    printf("%d ",y);//输出平均数的一半(取整)
    int k=0;
    while(1){
//输出获胜玩家名字
        if(ch[index][k]!=' '){
            printf("%c",ch[index][k]);
            k++;
        }else{
            break;
        }
    }
    return 0;
}

题目 7-2 组合数的和

给定 N 个非 0 的个位数字,用其中任意 2 个数字都可以组合成 1 个 2 位的数字。要求所有可能组合出来的 2 位数字的和。例如给定 2、5、8,则可以组合出:25、28、52、58、82、85,它们的和为330。
输入格式:
输入在一行中先给出 N(1 < N < 10),随后一行给出 N 个不同的非 0 个位数字。数字间以空格分隔。
输出格式:
输出所有可能组合出来的2位数字的和。
输入样例:
3
2 8 5
输出样例:
330
#include<stdio.h>
int main()
{
    int n;
    scanf("%d",&n);//读入n的值
    int num[n],i;
    for(i=0;i<n;i++){//读入n个数字
        scanf("%d",&num[i]);
    }
    int j;
    int sum=0;
    for(i=0;i<n;i++){
        for(j=i+1;j<n;j++){//通过两个for循环将两个不同的数字匹配到一起
//每次将匹配到的两个数字形成的两个数累加,最后得到sum的值
        sum+=num[i]*10+num[j]+num[j]*10+num[i];
        }
    }
    printf("%d",sum);//输出sum
    return 0;
}

题目 7-3 A-B

本题要求你计算 AB。不过麻烦的是, AB都是字符串 —— 即从字符串 A中把字符串 B所包含的字符全删掉,剩下的字符组成的就是字符串 AB
输入格式:
输入在2行中先后给出字符串 AB。两字符串的长度都不超过104,并且保证每个字符串都是由可见的ASCII码和空白字符组成,最后以换行符结束。
输出格式:
在一行中打印出 AB的结果字符串。
输入样例:
I love GPLT! It's a fun game!
aeiou
输出样例:
I lv GPLT! It's fn gm!
#include<stdio.h>
int main()
{
    char a[10001],b[10001];//这里我们不知道要读入的字符串的长度,但存在范围
//我们不妨令两个数组,且长度为范围的最大值
    int i=0,cnt1,cnt2;//这里我们赋两个变量,分别作为要读入字符串长度的“计量标”
    while((a[i]=getchar())!='\n'){//这里我们使用getchar读入字符,以'\n'结束
        i++;
    }
    cnt1=i;
    a[i]='\0';//结尾我们不妨赋值‘\0',作为字符串的结尾
    i=0;
    while((b[i]=getchar())!='\n'){
        i++;
    }
    cnt2=i;
    b[i]='\0';
    char c[cnt1];//这里为了方便,不妨我们令一个新的字符数组
    int j=0,cnt=0;
    for(i=0;i<cnt1;i++){//遍历数组a,查找是否存在于数组b中,我们以flag作为标记
        int flag=1;
        for(j=0;j<cnt2;j++){
//对于要查找的字符a[i]我们在字符数组b中作遍历
            if(a[i]==b[j]){
                flag=0;
            }
        }
        if(flag==1){//如果字符a[i]在字符b中不存在,我们将它赋给数组c,同时cnt++
            c[cnt++]=a[i];
        }
    }
    c[cnt]='\0';//为了方便输出,我们在结尾赋值为'\0'
    printf("%s",c);
    return 0;
}

题目 7-4 查验

一个合法的身份证号码由17位地区、日期编号和顺序编号加1位校验码组成。校验码的计算规则如下:
首先对前17位数字加权求和,权重分配为:{7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};然后将计算的和对11取模得到值 Z;最后按照以下关系对应 Z值与校验码 M的值:
Z:0 1 2 3 4 5 6 7 8 9 10
M:1 0 X 9 8 7 6 5 4 3 2
现在给定一些身份证号码,请你验证校验码的有效性,并输出有问题的号码。
输入格式:
输入第一行给出正整数 N(≤100)是输入的身份证号码的个数。随后 N行,每行给出1个18位身份证号码。
输出格式:
按照输入的顺序每行输出1个有问题的身份证号码。这里并不检验前17位是否合理,只检查前17位是否全为数字且最后1位校验码计算准确。如果所有号码都正常,则输出 All passed
输入样例1:
4
320124198808240056
12010X198901011234
110108196711301866
37070419881216001X
输出样例1:
12010X198901011234
110108196711301866
37070419881216001X
输入样例2:
2
320124198808240056
110108196711301862
输出样例2:
All passed
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 权重分配
int weight[17] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
// 校验码对应关系表
char code[11] = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
// 计算校验码
char get_check_code(char *id)
{
    int i, sum = 0;
    for (i = 0; i < 17; i++)
    {
        if (id[i] < '0' || id[i] > '9')
        {
            return ' ';
        }
        sum += (id[i] - '0') * weight[i];
    }
    return code[sum % 11];
}

int main()
{
    int n, i, j, flag;
    char id[19], check_code;
    scanf("%d", &n);
    flag = 1; // 默认所有号码都正常
    for (i = 0; i < n; i++)
    {
        scanf("%s", id);
        check_code = get_check_code(id);
        if (check_code != id[17])
        {
            printf("%s\n", id);
            flag = 0; // 有问题的号码,标记为不正常
        }
    }
    if (flag)
    {
        printf("All passed\n");
    }
    return 0;
}

题目 7-5 数字三角形

给出n,请输出一个直角边长度是n的数字直角三角形。所有数字都是 2 位组成的,如果没有 2 位则加上前导 0。
输入格式:
输入为一个正整数n,1≤n≤100。
输出格式:
输出为直角边长度是n的数字直角三角形,所有数字都是 2 位组成的,如果没有 2 位则加上前导 0,且当数字超过20时,重新从1开始。
输入样例:
5
输出样例:
1514100901
13110802
120703
0604
05
#include<stdio.h>
int main()
{
    int n;
    scanf("%d",&n);
    int a[n][n];//这里我令了一个二维数组来记录数字三角形数据的值
    int i=n-1,j=0,cnt=1,door=0;
    for(i=n-1;i>=0;i--){
//通过规律发现,数字从1开始递增时所在数组的位置的两个维度的角标在对应的斜着的直线上和相同
//这为我们准确赋给对应位置相应的值准备了条件
        if(door==0){
            for(j=0;j<=i;j++){
                if(cnt>20){
                    a[j][i-j]=cnt%20;
                }else{
                a[j][i-j]=cnt;
            }
            cnt++;
            }
            door=1;
        }else if(door==1){
            for(j=i;j>=0;j--){
                a[j][i-j]=cnt;
                cnt=cnt%20+1;
//这里我们每次对cnt除以20取余再加1,保证cnt在20以内作循环    
            }
            door=0;
        }
    }
    for(i=0;i<n;i++){
        for(j=0;j<n-i;j++){
            if(a[i][j]<10){
                printf("0");
            }
            printf("%d",a[i][j]);
        }
        if(i<n-1){
            printf("\n");    
        }
    }
    return 0;
}

综合随性复习笔记

C语言基础

1.进制数转换输出

%o表示八进制数

%x表示十六进制数

2.格式控制字符%c能否读入空格字符和'\n'?

上述简易代码我们注意到格式控制字符%c是能读入空格的

我们发现它还能读入转义字符'\n'回车

3.格式控制字符%s能否读入空格字符和'\n'?

通过这个简易代码演示我们发现,格式控制字符遇到空格和回车停止读入

即不能读入空格和回车

4.C语言的逗号运算

表达式1,表达式2;

这里先求解表达式1,再求解表达式2,

注意整个逗号运算的返回值是表达式2的值,而不是表达式1中变量被赋值表达式2的结果

例如:a=3,4*a;这里先进行表达式1,a被赋值为3,然后进行表达式2,4*a=12,然后整个逗号表达式的返回值即为12,但a的值只被赋值了3,之后没有变动仍是3

5.scanf函数返回值

scanf函数读不到数据时返回EOF,读到数据时是正确读到的数据个数

在 C语言中,EOF 是一个宏定义,它代表"end of file",表示文件结束标志。EOF 是一个特殊的字符,它的值在不同的编译器中可能不同,但总是负数。在大多数系统中,EOF 的值为 -1。(此句转载自C语言中文网http://c.biancheng.net/

6.sizeof函数对应操作数为字符串时

sizeof函数在计算字符串中字符的个数时会自动加上字符串结尾的字符'\0'

7.常见转义字符

\n

\+字母 一般为一个转义字符

\+数字(8进制)+数字(8进制)+数字(8进制) 表示对应三个数字所表示的八进制数

\x+数字(16进制)+数字(16进制) 表示对应的16进制数

\'表示一个单引号字符

\"表示一个双引号字符

\?表示一个问号

\\代表一个反斜线字符

8.条件运算符

(条件判断)?a:b

若为真,则表达式返回a

若为假,则表达式返回b

9.格式限定符%e,%E

%e指以指数形式输入或输出小数,可用来限定实数的输入和输出,

输入输出时的格式为 尾数e指数(这里指数必须为整数) 2e-7表示2乘以10的-7次方

%E同理

10.C语言几种运算的运算顺序

赋值运算>算术运算>条件运算

11.关于“%”

它可以是格式控制符用于两个数间取模运算

那么想要输出%该怎么做呢?

键盘敲入两个%即可

两个%连在一起时,表示告诉编译器,此时的%不是一个格式控制符,而是一个普通字符

12.表达式x==0与表达式!x等价

表达式的结果为逻辑值

对于!x

  • 85
    点赞
  • 217
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 29
    评论
程序设计竞赛相关代码、设计文档、使用说明,供学习参考 程序设计竞赛相关代码、设计文档、使用说明,供学习参考 程序设计竞赛相关代码、设计文档、使用说明,供学习参考 程序设计竞赛相关代码、设计文档、使用说明,供学习参考 程序设计竞赛相关代码、设计文档、使用说明,供学习参考 程序设计竞赛相关代码、设计文档、使用说明,供学习参考 程序设计竞赛相关代码、设计文档、使用说明,供学习参考 程序设计竞赛相关代码、设计文档、使用说明,供学习参考 程序设计竞赛相关代码、设计文档、使用说明,供学习参考 程序设计竞赛相关代码、设计文档、使用说明,供学习参考 程序设计竞赛相关代码、设计文档、使用说明,供学习参考 程序设计竞赛相关代码、设计文档、使用说明,供学习参考 程序设计竞赛相关代码、设计文档、使用说明,供学习参考 程序设计竞赛相关代码、设计文档、使用说明,供学习参考 程序设计竞赛相关代码、设计文档、使用说明,供学习参考 程序设计竞赛相关代码、设计文档、使用说明,供学习参考 程序设计竞赛相关代码、设计文档、使用说明,供学习参考 程序设计竞赛相关代码、设计文档、使用说明,供学习参考 程序设计竞赛相关代码、设计文档、使用说明,供学习参考 程序设计竞赛相关代码、设计文档、使用说明,供学习参考 程序设计竞赛相关代码、设计文档、使用说明,供学习参考 程序设计竞赛相关代码、设计文档、使用说明,供学习参考 程序设计竞赛相关代码、设计文档、使用说明,供学习参考 程序设计竞赛相关代码、设计文档、使用说明,供学习参考

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

彩色马铃薯郭巴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值