C语言编程超全练习题(二)

前言

继上文。此为第四部分-第六部分。


篇幅所限,将文章分为了三篇、九部分。下面是文章链接。


练习题总览

    第一部分
        韩信点兵
        兰州烧饼
        进制转换
        第几天?
        成绩转换
    第二部分
        求实数的绝对值。
        计算球体积
        两点距离
        ASCII码排序
        数值统计
    第三部分
        最小公倍数
        公约数和公倍数
        5个数求最值
        素数筛子算法
        分数加减法
    第四部分
        第二小整数
        奇偶数分离
        奇偶位互换
        统计硬币
        汉字统计
    第五部分
        偶数求和
        杨辉三角
        统计字符
        完数
        素数回文
    第六部分
        快速排序
        开门人和关门人
        鸡兔同笼
        日期计算
        开灯问题
    第七部分
        字符串替换
        字母统计
        字符串逆序输出
        交换输出
        比较字母大小
    第八部分
        猴子吃桃问题
        九九乘法表
        16进制的简单运算
        三角形面积
        平方和与立方和
    第九部分
        水仙花数
        多项式求和
        绝对值排序
        首字母变大写
        a/b + c/d

第四部分

第二小整数

求n个整数中倒数第二小的数。每一个整数都独立看成一个数,比如,有三个数分别是1,1,3,那么,第二小的数就是1。

  • 输入

输入包含多组测试数据。
输入的第一行是一个整数C,表示有C测试数据;
每组测试数据的第一行是一个整数n,表示本组测试数据有n个整数(2<=n<=10),接着一行是 n个整数 (每个数均小于100);

  • 输出
    请为每组测试数据输出第二小的整数,每组输出占一行。
#include <stdio.h>

int main(){
    int T;
    int n;
    int i;
    int min;
    int min_flag;
    int number[11];
    
    scanf("%d",&T);
    
    while(T--){
        scanf("%d",&n);
        
        for(i=0;i<n;i++){
            scanf("%d",&number[i]);
            
            if(i==0){
                min=number[0];
                min_flag=0;
            }
                
            if(number[i]<min){
                min=number[i];
                min_flag=i;
            }
        } 
        
        for(i=0;i<n;i++){
            if(i!=min_flag){
                min=number[i];
                break;
            }
        } 
        
        for(i=0;i<n;i++){
            if(i!=min_flag && number[i]<min)
                min=number[i];
        }
        
        printf("%d\n",min);
    }
            
    return 0;
}

奇偶数分离

有一个整型偶数n(2<= n <=10000),你要做的是:先把1到n中的所有奇数从小到大输出,再把所有的偶数从小到大输出。

  • 输入
    第一行有一个整数i(2<=i<30)表示有 i 组测试数据;每组有一个整型偶数n。
  • 输出
    第一行输出所有的奇数。第二行输出所有的偶数
#include <stdio.h>

int main(){
    int T;
    int i;
    int n;
    
    scanf("%d",&T);
    
    while(T--){
        scanf("%d",&n);
        for(i=1;i<=n;i++){
            if(i%2==1){
                if(i==1)
                    printf("%d",i);
                
                else
                    printf(" %d",i);
            }
        }
        
        printf("\n");
        
        for(i=1;i<=n;i++){
            if(i%2==0){
                if(i==2)
                    printf("%d",i);
                
                else
                    printf(" %d",i);
            }
        }
        
        printf("\n");
        
        if(T!=0)
            printf("\n");
    }

    return 0;
}

奇偶位互换

给定一个长度为偶数位的0,1字符串,请编程实现串的奇偶位互换。

  • 输入

输入包含多组测试数据;
输入的第一行是一个整数C,表示有C测试数据;
接下来是C组测试数据,每组数据输入均为0,1字符串,保证串长为偶数位(串长<=50)。

  • 输出
    请为每组测试数据输出奇偶位互换后的结果;每组输出占一行。
#include <stdio.h>
#include <string.h>

int main(){
    int T;
    char s[51];
    int length;
    char temp;
    int i;
    
    scanf("%d",&T);
    
    while(T--){
        scanf("%s",s);
        length=strlen(s);
        
        for(i=0;i<length-1;i+=2){
            temp=s[i];
            s[i]=s[i+1];
            s[i+1]=temp;
        }
        
        printf("%s\n",s);
    }
            
    return 0;
}

统计硬币

假设一堆由1分、2分、5分组成的n个硬币总面值为m分,求一共有多少种可能的组合方式(某种面值的硬币可以数量可以为0)。

  • 输入
    输入数据第一行有一个正整数T,表示有T组测试数据;接下来的T行,每行有两个数n,m,n和m的含义同上。
  • 输出
    对于每组测试数据,请输出可能的组合方式数;每组输出占一行。
#include <stdio.h>

int main(){
    int T;
    int amount;
    int sum;
    int one_amount;
    int two_amount;
    int five_amount;
    int a;
    int b;
    int c;
    int result;
    
    scanf("%d",&T);
    
    while(T--){
        result=0;
        scanf("%d%d",&amount,&sum);
        one_amount=sum/1;
        two_amount=sum/2;
        five_amount=sum/5;
        
        for(a=0;a<=one_amount;a++){
            for(b=0;b<=two_amount;b++){
                for(c=0;c<=five_amount;c++){
                    if((a+b+c)==amount && (a*1+b*2+c*5)==sum)
                        result++;
                }
            }
        }
        printf("%d\n",result);
    }
            
    return 0;
}

汉字统计

统计给定文本文件中汉字的个数。

  • 输入
    输入文件首先包含一个整数n,表示测试实例的个数,然后是n段文本。
  • 输出
    对于每一段文本,输出其中的汉字的个数,每个测试实例的输出占一行。
#include <stdio.h>

int main(){
    int T;
    char c;
    int amount;
    
    scanf("%d",&T);
    getchar();
    
    while(T--){
        amount=0;
        while((c=getchar())!='\n'){
            if(c<0 || c>127)
                amount++;
        }
        printf("%d\n",amount/2);
    }
        
    
    return 0;
}

第五部分

偶数求和

有一个长度为n(n<=100)的数列,该数列定义为从2开始的递增有序偶数,现在要求你按照顺序每m个数求出一个平均值,如果最后不足m个,则以实际数量求平均值。编程输出该平均值序列。

  • 输入
    输入数据有多组,每组占一行,包含两个正整数n和m,n和m的含义如上所述。
  • 输出
    对于每组输入数据,输出一个平均值序列,每组输出占一行。
#include <stdio.h>

int main(){
    int sequence[101];
    int i;
    int j;
    int n;
    int m;
    int result;
    int remainder;
    int flag;
    
    for(i=0;i<101;i++)
        sequence[i]=(i+1)*2;
        
    while((scanf("%d%d",&n,&m))!=EOF){
        result=0;
        j=1;
        flag=0;
        
        remainder=n%m;
        
        for(i=0;i<=n;i++){
            if(j<=m){
                result+=sequence[i];
            }
            
            else{
                if(flag==0)
                    printf("%d",result/m);
                    
                else
                    printf(" %d",result/m);
                    
                flag=1;
                j=1;
                result=sequence[i];
            }    
            j++;
        }
        
        if(remainder){
            printf(" %d",(result-sequence[n])/remainder);
        }
        
        printf("\n");
    }
        
        
            
    
    return 0;
}

杨辉三角

还记得中学时候学过的杨辉三角吗?具体的定义这里不再描述,你可以参考以下的图形:

1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1

  • 输入
    输入数据包含多个测试实例,每个测试实例的输入只包含一个正整数n(1<=n<=30),表示将要输出的杨辉三角的层数。
  • 输出
    对应于每一个输入,请输出相应层数的杨辉三角,每一层的整数之间用一个空格隔开,每一个杨辉三角后面加一个空行。
#include <stdio.h>   //本来不会做的,但是编着编着就出来了,么么哒 

int main(){
    int n;
    int triangle[31][31];
    int i;
    int j;
    
    while((scanf("%d",&n))!=EOF){
        for(i=0;i<31;i++)
            for(j=0;j<31;j++)
                triangle[i][j]=0;
        
        triangle[0][0]=1;
        triangle[1][0]=1;
        triangle[1][1]=1;
                
        for(i=2;i<n;i++){
            triangle[i][0]=1;
            triangle[i][i]=1;
            for(j=1;j<=i;j++){
                triangle[i][j]=triangle[i-1][j]+triangle[i-1][j-1];
            }
        }
        
        for(i=0;i<n;i++){
            for(j=0;j<n;j++){
                if(triangle[i][j]!=0){
                    if(j==0)
                        printf("%d",triangle[i][j]);
                        
                    else
                        printf(" %d",triangle[i][j]);
                }
            }
                
            printf("\n");
        }
        
        printf("\n");
        
    } 
    return 0;
}

统计字符

统计一个给定字符串中指定的字符出现的次数

  • 输入
    测试输入包含若干测试用例,每个测试用例包含2行,第1行为一个长度不超过5的字符串,第2行为一个长度不超过80的字符串。注意这里的字符串包含空格,即空格也可能是要求被统计的字符之一。当读到'#'时输入结束,相应的结果不要输出。
  • 输出

对每个测试用例,统计第1行中字符串的每个字符在第2行字符串中出现的次数,按如下格式输出:
c0 n0
c1 n1
c2 n2
...
其中ci是第1行中第i个字符,ni是ci出现的次数。

#include <stdio.h> 
#include <string.h>

int main(){
    char s1[6];
    char s2[81];
    int s1_length;
    int s2_length;
    int i;
    int j;
    int time;
    char c;

    while(1){
        i=0;    //s1包含空格
        while((c=getchar())!='\n'){
            s1[i]=c;
            i++;
        }
        s1[i]='\0';

        if(s1[0]=='#')    
            break;

        i=0;    //s2包含空格
        while((c=getchar())!='\n'){
            s2[i]=c;
            i++;
        }
        s2[i]='\0';

        s1_length=strlen(s1);
        s2_length=strlen(s2);

        for(i=0;i<s1_length;i++){
            time=0;
            for(j=0;j<s2_length;j++){
                if(s1[i]==s2[j])
                    time++;
            }

            printf("%c %d\n",s1[i],time);
        }
    }
    return 0;
}

完数

完数的定义:如果一个大于1的正整数的所有因子之和等于它的本身,则称这个数是完数,比如6,28都是完数:6=1+2+3;28=1+2+4+7+14。

  • 输入
    输入数据包含多行,第一行是一个正整数n,表示测试实例的个数,然后就是n个测试实例,每个实例占一行,由两个正整数num1和num2组成,(1<num1,num2<10000) 。
  • 输出
    对于每组测试数据,请输出num1和num2之间(包括num1和num2)存在的完数个数。
#include <stdio.h>

int if_perfect_number(int number);

int main(){
    int T;
    int number1;
    int number2;
    int temp;
    int i;
    int amount;

    scanf("%d",&T);

    while(T--){
        amount=0;
        scanf("%d%d",&number1,&number2);

        if(number1>number2){
            temp=number1;
            number1=number2;
            number2=temp;
        }

        for(i=number1;i<=number2;i++){
            if(if_perfect_number(i)==1)
                amount++;
        }

        printf("%d\n",amount);
    }
    return 0;
}

int if_perfect_number(int number){
    int i;
    int sum;

    sum=0;

    for(i=1;i<=number/2;i++){
        if(number%i==0)
            sum+=i;
    }

    if(sum==number)
        return 1;

    else
        return 0;
}

素数回文

xiaoou33对既是素数又是回文的数特别感兴趣。比如说151既是素数又是个回文。现在xiaoou333想要你帮助他找出某个范围内的素数回文数,请你写个程序找出 a 跟b 之间满足条件的数。(5 <= a < b <= 100,000,000);

  • 输入
    这里有许多组数据,每组包括两组数据a跟b。
  • 输出
    对每一组数据,按从小到大输出a,b之间所有满足条件的素数回文数(包括a跟b)每组数据之后空一行。
#include <stdio.h>
#include <string.h>
#include <math.h>

#define N 10000000   //9999999是题目要求范围的最大回文数
char flag[N];

int palindrome_number(int number);

int main(){
    int i;
    int j;
    int a;
    int b;

    memset(flag,'0',N);
    flag[0]='1';
    flag[1]='1';

    for(i=2;i<=sqrt((double)N);i++){
        if(flag[i]=='0'){
            for(j=i*i;j<N;j+=i)
                flag[j]='1';
        }
    }

    while(scanf("%d%d",&a,&b)!=EOF){
        for(i=a;i<=b;i++){
            if(i>N-1)
                continue;

            if(palindrome_number(i)==1 && flag[i]=='0')
                printf("%d\n",i);
        }

        printf("\n");
    }

    return 0;
}

int palindrome_number(int number){
    int array[9];
    int i;
    int length;
    int flag;

    i=0;
    while(number){
        array[i]=number%10;
        i++;
        number/=10;    
    }
    length=i;

    flag=0;
    for(i=0;i<length/2;i++){
        if(array[i]!=array[length-i-1]){
            flag=1;
            break;
        }
    }

    if(flag==1)
        return 0;

    else
        return 1;
}

第六部分

快速排序

给你n个整数,请按从大到小的顺序输出其中前m大的数。

  • 输入
    每组测试数据有两行,第一行有两个数n,m(0<n,m<1000000),第二行包含n个各不相同,且都处于区间[-500000,500000]的整数。
  • 输出
    对每组测试数据按从大到小的顺序输出前m大的数。
#include <stdio.h>

void quickSort(int a[],int left,int right);
int array[1000001];

int main(){
    int n;
    int m;
    int i;
    
    while(scanf("%d%d",&n,&m)!=EOF){
        for(i=0;i<n;i++)
            scanf("%d",&array[i]);
            
        quickSort(array,0,n-1);
        
        for(i=n-1;i>n-m-1;i--){
            if(i==n-1)
                printf("%d",array[i]);
                
            else
                printf(" %d",array[i]);
        }
        
        printf("\n");
    }
    
    return 0;
}

void quickSort(int a[],int left,int right){
    int i;
    int j;
    int temp;
    
    i=left;
    j=right;
    temp=a[left];
    
    if(left>=right)
        return;
        
    while(i!=j){
        while(i<j && a[j]>=temp)
            j--;
            
        if(i<j){
            a[i]=a[j];
        }
            
            
        while(i<j && a[i]<=temp)
             i++;
             
        if(i<j){
            a[j]=a[i];
        }
    }
    a[i]=temp;
    
    quickSort(a,left,i-1);
    quickSort(a,i+1,right);    
}

开门人和关门人

每天第一个到机房的人要把门打开,最后一个离开的人要把门关好。现有一堆杂乱的机房签

到、签离记录,请根据记录找出当天开门和关门的人。

  • 输入

测试输入的第一行给出记录的总天数N ( > 0 )。下面列出了N天的记录。
每天的记录在第一行给出记录的条目数M ( > 0 ),下面是M行,每行的格式为

证件号码 签到时间 签离时间

其中时间按“小时:分钟:秒钟”(各占2位)给出,证件号码是长度不超过15的字符串。

  • 输出

对每一天的记录输出1行,即当天开门和关门人的证件号码,中间用1空格分隔。
注意:在裁判的标准测试输入中,所有记录保证完整,每个人的签到时间在签离时间之前,
且没有多人同时签到或者签离的情况。

#include <stdio.h>
#include <string.h>

int main(){
    int N;
    int M;
    int i;
    char ID[16];
    char minID[16];
    char maxID[16];
    char s1[9];
    char s2[9];
    char time1[7];
    char time2[7];
    char minTime[7];
    char maxTime[7];

    scanf("%d",&N);

    while(N--){
        scanf("%d",&M);

        for(i=0;i<M;i++){
            scanf("%s%s%s",ID,s1,s2);
            time1[0]=s1[0];
            time1[1]=s1[1];
            time1[2]=s1[3];
            time1[3]=s1[4];
            time1[4]=s1[6];
            time1[5]=s1[7];
            time1[6]='\0';

            time2[0]=s2[0];
            time2[1]=s2[1];
            time2[2]=s2[3];
            time2[3]=s2[4];
            time2[4]=s2[6];
            time2[5]=s2[7];
            time2[6]='\0';

            if(i==0){
                strcpy(minID,ID);
                strcpy(maxID,ID);
                strcpy(minTime,time1);
                strcpy(maxTime,time2);
                continue;
            }

            if(strcmp(time1,minTime)<0){
                strcpy(minID,ID);
                strcpy(minTime,time1);
            }

            if(strcmp(time2,maxTime)>0){
                strcpy(maxID,ID);
                strcpy(maxTime,time2);
            }
        }

        printf("%s %s\n",minID,maxID);


    }
    
    
    return 0;
}

鸡兔同笼

已知鸡和兔的总数量为n,总腿数为m。输入n和m,依次输出鸡和兔的数目,如果无解,则输出“No answer”(不要引号)。

  • 输入
    第一行输入一个数据a,代表接下来共有几组数据,在接下来的(a<10)、a行里,每行都有一个n和m.(0<m,n<100)
  • 输出
    输出鸡兔的个数,或者No answer
#include <stdio.h> 

int main(){
    int T;
    int n;
    int m;
    
    scanf("%d",&T);
    
    while(T--){
        scanf("%d%d",&n,&m);
        
        if((m-2*n)>=0 && (m-2*n)%2==0 && (4*n-m)>=0 && (4*n-m)%2==0)
            printf("%d %d\n",(4*n-m)/2,(m-2*n)/2);
            
        else
            printf("No answer\n");    
    }
    return 0;
}

日期计算

如题,输入一个日期,格式如:2010 10 24 ,判断这一天是这一年中的第几天。

  • 输入
    第一行输入一个数N(0<N<=100),表示有N组测试数据。后面的N行输入多组输入数据,每行的输入数据都是一个按题目要求格式输入的日期。
  • 输出
    每组输入数据的输出占一行,输出判断出的天数n
#include <stdio.h> 

int main(){
    int T;
    int a;
    int b;
    int c;
    int i;
    int day[13];
    int amount;
    
    day[1]=31;
    day[2]=28;
    day[3]=31;
    day[4]=30;
    day[5]=31;
    day[6]=30;
    day[7]=31;
    day[8]=31;
    day[9]=30;
    day[10]=31;
    day[11]=30;
    day[12]=31;
    
    scanf("%d",&T);
    
    while(T--){
        scanf("%d%d%d",&a,&b,&c);
        
        amount=0;
        for(i=1;i<b;i++)
            amount+=day[i];
        amount+=c;
        
        if((a%400==0 || (a%4==0 && a%100!=0)) && i>=3)
            amount++;
            
        printf("%d\n",amount);
    }
    return 0;
}

开灯问题

有n盏灯,编号为1~n,第1个人把所有灯打开,第2个人按下所有编号为2 的倍数的开关(这些灯将被关掉),第3 个人按下所有编号为3的倍数的开关(其中关掉的灯将被打开,开着的灯将被关闭),依此类推。一共有k个人,问最后有哪些灯开着?输入:n和k,输出开着的灯编号。k≤n≤1000

  • 输入
    输入一组数据:n和k
  • 输出
    输出开着的灯编号
#include <stdio.h> 
#include <string.h>

int main(){
    int n;
    int k;
    int flag[1001];
    int i;
    int j;
    
    scanf("%d%d",&n,&k);
    memset(flag,0,sizeof(int)*1001);
    
    for(i=1;i<=k;i++){
        for(j=1;j<=n;j++){
            if(j%i==0){
                if(flag[j-1]==0)
                    flag[j-1]=1;
                    
                else
                    flag[j-1]=0;
            }
        }
    }
    
    for(i=0;i<n;i++){
        if(flag[i]==1){
            printf("%d",i+1);
            flag[i]=0;
            break;
        }
    }
    
    for(i=0;i<n;i++){
        if(flag[i]==1)
            printf(" %d",i+1);
    }
    
    printf("\n");
    
    return 0;
}

特别感谢:zqxLonely

最后修改:2018 年 05 月 21 日 11 : 47 AM
生活需要一些仪式感,比如手冲一杯咖啡:)

发表评论