十五个题分析总结

本文通过分析和解决七个不同的编程题目,涵盖了数据转换、数字特性、序列操作和数学计算等多个方面,展示了C/C++在算法和逻辑处理上的应用。每个题目包括题目描述、解题思路、源代码和总结,帮助读者理解和掌握各种编程技巧和常见算法。
摘要由CSDN通过智能技术生成

1题目简述

输入一个百分制的成绩t,将其转换成对应的等级,具体转换规则如下:

90~100为A;

80~89为B;

70~79为C;

60~69为D;

0~59为E;

注意 输入数据有多组,每组占一行,由一个整数组成。对于每组输入数据,输出一行。如果输入数据不在0~100范围内,请输出一行:“Score is error!”

2题目分析

这道题结合if语句和while语句,利用查表法的方式运行。注意不能漏掉小于零的情况。

 

3源代码

 

/* HDU2004 成绩转换 */

 

#include <stdio.h>

 

int main(void)

{

    int score;

    char convert[] = "EEEEEEDCBAA";

 

    while(scanf("%d", &score) != EOF) {

          if(score < 0 || score > 100)

              printf("Score is error!\n");

          else

              printf("%c\n", convert[score/10]);

    }

 

    return 0;

}

4总结

注意不要漏掉小于零的情况,要牢牢掌握if、while语句的使用

1题目简述

“水仙花数”是指一个三位数,它的各位数字的立方和等于其本身,比如:153=1^3+5^3+3^3。如果有多个,则要求从小到大排列在一行内输出,之间用一个空格隔开;如果给定的范围内不存在水仙花数,则输出no;每个测试实例的输出占一行。现在要求输出所有在m和n范围内的水仙花数。

2题目分析

把握住i/100是百位数
i/10%10是十位数
i%10是个位数 只要用POW函数使得这三位数的三次幂为他本身即为水仙花数。

3源代码

#include<iostream>

#include<cmath>

using namespace std;

int main()

{

    int l,r;

    while(cin >> l >> r)

    {

        int count = 0;

        for(int i=l;i<=r;i++)

        {

            int sum = pow(i%10,3) + pow((i/10)%10,3) + pow(i/100,3);

            if(sum == i){

 count++;

                if(count == 1)

                    cout << i;

                else

                    cout << " " << i;

            }

        }

        if(count == 0)

            cout << "no";

        cout << endl;

    }

    return 0;

}

4总结

考察了百位数 个位数 十位数是怎样表达的。

 

 

 

1题目简述

给你n个整数,求他们中所有奇数的乘积。并且每个输出的整数占一行

2题目分析

假设每组数据必定至少存在一个奇数,其中,先判断他是不是奇数,如果是奇数,就把所有奇数相乘并输出。

3源代码

#include <iostream>

 

using namespace std;

 

int main(void)

{

    int n,*input_num,odd_sum=1;

    while(cin>>n)

    {

        input_num=new int[n];

        for(int i=0; i<n; i++)

        {

            cin>>input_num[i];

            if(input_num[i]%2!=0)

            {

                odd_sum*=input_num[i];

 

            }

        }

        cout<<odd_sum<<endl;

        odd_sum=1;

        delete input_num;//释放空间

    }

    return 0;

}

4总结

先判定后运算再输出的类型,要牢记for语句的作用

1题目简述

对表达式n^2+n+41,当n在(x,y)范围内取整数值时(包括x,y)

(-39<=x<y<=50),判定该表达式的值是否都为素数。

输入数据有多组,每组占一行,由两个整数x,y组成,当x=0,y=0时,表示输入结束,该行不做处理。

对于每个给定范围内的取值,如果表达式的值都为素数,则输出"OK",否则请输出“Sorry”,每组输出占一行。

 

2题目分析

只要判断 6x两侧的数是否为素数即可,因为合数总是可以写成素数的乘积,那么我们直接用n去除以质数就可以。而质数一定是 6x 两侧的数(当 n >= 5 时,n不是素数时,n 不含质因子2,3) , 6x 两侧的数是大于素数的集合,因此可以用n 除以 6x 两侧的数,即if(n % i == 0 || n % (i +2) == 0)时,不是素数。

3源代码

#include<cstdio>

#include<cstring>

#include<iostream>

using namespace std;

int main()

{

    bool prime[3000];

    memset(prime,true,sizeof(prime));

    prime[0]=prime[1]=false;

    for(int i=2;i<3000;i++)

        if(prime[i])

            for(int j=2*i;j<3000;j+=i)

                prime[j]=false;

    int x,y;

    while(scanf("%d%d",&x,&y)&&(x||y))

    {

        int flag=1;

        for(int i=x;i<=y;i++)

        {

            int n=i*i+i+41;

            if(!prime[n])

            {

                flag=0;

                break;

            }

        }

        if(flag)

            printf("OK\n");

        else

            printf("Sorry\n");

    }

    return 0;

}

4总结

这个题的思路是利用了一个素数的倍数都不是素数。

1题目简述

多项式的描述如下:
1 - 1/2 + 1/3 - 1/4 + 1/5 - 1/6 + ...
现在请你求出该多项式的前n项的和。

输入数据由2行组成,首先是一个正整数m(m<100),表示测试实例的个数,第二行包对于每个测试实例n,要求输出多项式前n项的和。每个测试实例的输出占一行,结果保留2位小数。

含m个正整数,对于每一个整数(不妨设为n,n<1000),求该多项式的前n项的和。

 

2题目分析

 

3源代码

#include<stdio.h>

#include<math.h>

int main()

{

   int m,n,i,j;

   double num,a;

   while(scanf("%d",&m)!=EOF)

    {

       for(i=0;i<m;i++)

         { 

            scanf("%d",&n);

            if(n==0) num=0.0;

            else

             {

               a=1;num=1.0;

               for(j=0;j<n-1;j++)

                 { 

                    a++;

                    num+=pow(-1,a-1)/a;

                 }

             }

            printf("%.2f\n",num);

         }

    }

   return 0;

}

4总结

要牢牢掌握pow函数的作用,

1题目简述

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

2分析

用一个计数器,记录加的次数,到了指定的次数,就可以该值。注意在输出空格是怎么输出的

3源代码

#include<stdio.h>

int main()

{

        int n,m;

        int i,temp,sum,count;

        while(~scanf("%d%d",&n,&m))

        {

               temp=sum=count=0;

               for(i=1;i<=n;i++)

               {

                       sum+=2*i;

                       count++;

                       if(count==m)

                       {

                               if(temp==0)   temp=1;//控制空格的

                               else   printf(" ");

                               printf("%d",sum/m);

                               sum=count=0;

                       }

               }

               if(count!=0)//考虑不足m的情况

               {

                       if(temp==0)   temp=1;

                       else   printf(" ");

                       printf("%d",sum/count);

                }

               printf("\n");

        }

        return 0;

}

4总结

关键在于如何计算有序偶数的平均值。

1题目简述

选手得分规则为去掉一个最高分和一个最低分,然后计算平均得分,请编程输出某选手的得分。 输入数据有多组,每组占一行,每行的第一个数是n(2<n<=100),表示评委的人数,然后是n个评委的打分。

对于每组输入数据,输出选手的得分,结果保留2位小数,每组输出占一行。

 

2题目分析

可以在输入的时候标记最大和最小的,然后最后统一处理

 

3源代码

#include<stdio.h>

int main()

{

        int n,i;double s,x,max,min;

        while(~scanf("%d",&n))

        {

               scanf("%lf",&x);

               s=max=min=x;

               for(i=1;i<n;++i)

               {

                       scanf("%lf",&x);

                       s+=x;//累加总成绩

                       max=(x>max)?x:max;//判断是否是最值

                       min=(x<min)?x:min;

               }

               printf("%.2lf\n",(s-max-min)/(n-2));//输出....

        }

        return 0;

}

4总结

这道题巧妙的利用了判别最大值和最小值后再取平均值,降低了用数组编程的复杂性。

1题目简述

母牛每年年初生一头小母牛。第四个年头开始,每年年初也生一头小母牛。请编程实现在第n年的时候,共有多少头母牛?

输入数据由多个测试实例组成,每个测试实例占一行,包括一个整数n(0<n<55),n的含义如题目中描述。
n=0表示输入数据的结束,不做处理。

对于每个测试实例,输出在第n年的时候母牛的数量。

 

2分析

首先看输入输出,当年数小于等于4的时候,第几年就有几头牛,当n大于4的时候,这时候第一年出生的小母牛又可以生小牛,要考虑到小牛是否可以生了。每年都有有a(n-1)头母牛,那么就要知道这一年出生的母牛有多少。第n-3年有多少头母牛,到了第n年这些牛都能生小牛了,因此出生数为(n-3) 从而今年的母牛数为a(n)=a(n-1)+a(n-3) 因此得到递推公式:a(1)=1,a(2)=2,a(3)=3,a(n)=a(n-1)+a(n-3)(n>=4)

3源代码

#include <cstdio>

int a[60];//开的稍微大一点

int main()

{

    int n;

    a[1] = 1;

    a[2] = 2;

    a[3] = 3;

    a[4] = 4;

    for(int i=5;i <= 60;i++)

        a[i] = a[i-1] + a[i-3];

    while(~scanf("%d",&n) && n != 0){//等价于scanf("%d",&n) != EOF

        printf("%d\n",a[n]);

    }

    return 0;

}

 

4总结

利用递归的方法编程

1题目简述

有如下方程:Ai = (Ai-1 + Ai+1)/2 - Ci (i = 1, 2, 3, .... n).
若给出A0, An+1, C1, C2, .....Cn.

请编程计算A1 = ?
对于每个实例,首先是一个正整数n,(n <= 3000); 然后是2个数a 0, a n+1.接下来的n行每行有一个数c i(i = 1, ....n);输入以文件结束符结束。

 对于每个测试实例,用一行输出所求得的a1(保留2位小数).

 

 

2分析

这道题的关键是寻找规律,规律如下

n=1;2A1=A0+A2-2C1

n=2;3A1=2A0+A3-4C1-2C2

n=3;4A1=3A0+A4-6C1-4C2-2C3

n=5;5A1=4A0+A5-8C1-6C2-4C3-2C4

 

 

3源代码

#include<stdio.h>

int main(){

    double a0,a1,ai,c[3010];

    int n;

    while(~scanf("%d",&n)){

        scanf("%lf%lf",&a0,&ai);

        a1=n*a0+ai;

        int k=n;

        for(int i=1;i<=n;i++){

            scanf("%lf",&c[i]);

            a1=a1-k*2*c[i];

            k--;

        }

        printf("%.2lf\n",a1/(n+1));

    }

    return 0;

}

 

4总结

找到规律后利用找出的式子编程即可。

1题目简述

妈妈每天都要出去买菜,但是回来后,兜里的钱也懒得数一数,到底花了多少钱真是一笔糊涂帐。现在好了,作为好儿子(女儿)的你可以给她用程序算一下。

 

输入含有一些数据组,每组数据包括菜种(字串),数量(计量单位不论,一律为double型数)和单价(double型数,表示人民币元数),因此,每组数据的菜价就是数量乘上单价啊。菜种、数量和单价之间都有空格隔开的。

 

 

支付菜价的时候,由于最小支付单位是角,所以总是在支付的时候采用四舍五入的方法把分头去掉。最后,请输出一个精度为角的菜价总量。

 

2分析

直接按照!=EOF编程就可以,由于题目要求是只付一次总价

所以最后可以四舍五入,由此编程可以输出正确结果。

       

3源代码

 

#include<stdio.h>

char nam[110];

int main()

{

        double num,mon;

        double sum=0;

        while(scanf("%s%lf%lf",nam,&num,&mon)!=EOF)

        {

               sum+=num*mon;

        }

        printf("%.1lf\n",sum);

        return 0;

}

 

4总结

这道题没有表明结束是什么,所以只要

联想到应用不等于EOF即可。

十一

1题目简述

n(n<=100)个整数,已经按照从小到大顺序排列好,现在另外给一个整数x,请将该数插入到序列中,并使新的序列仍然有序。 Input 输入数据包含多个测试实例,每组数据由两行组成,第一行是nm,第二行是已经有序的n个数的数列。nm同时为0标示输入数

 

2分析

m赋值为a[n]然后对新数列用快排排序,再输出。注意要牢记*gsort可以升序和逆序排列

3源代码

#include<stdio.h>

#include<stdlib.h>

int cmp(const void*p1,const void*p2)

{

return *(int*)p1-*(int*)p2;

}

int main()

{

int n,m,i,a[111];

while(scanf("%d%d",&n,&m)!=EOF)

{

if(m==0&&n==0)break;

a[n]=0;

for(i=0;i<n;i++)

scanf("%d",&a[i]);

a[n]=m;

qsort(a,n+1,sizeof(a[0]),cmp);

for(i=0;i<n+1;i++)

{

if(i==0)

printf("%d",a[0]);

else

printf(" %d",a[i]);

}

printf("\n");

}

return 0;

}

4总结

妙用了快排的方式来完成编程

 

十二

1题目简述

有一楼梯共M级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第M级,共有多少种走法?

“2分析

一开始要找递推规律,每到达一个阶梯,一定是从前一个或者前两个楼梯走过来的,那它的走法就是前一个走法和前两个走法的和。

即为x[i]=x[i-1]+x[i-2]

 

3源代码

#include<iostream>

#include<cstdio>

#include<cstring>

using namespace std;

int x[50];

int main()

{

    int T;

    scanf("%d",&T);

    while(T--)

    {

        int a;

        scanf("%d",&a);

        a--;

        x[1]=1;

        x[2]=2;

        for(int i=3;i<=a;i++)

        {

            x[i]=x[i-1]+x[i-2];

        }

        printf("%d\n",x[a]);

    }

    return 0;

}

 

4总结

注意找规律,然后将找出的式子编程进去。

十三

1题目简述

输入一个十进制数N,将它转换成R进制数输出每个输出占一行。如果R大于10,则对应的数字规则参考16进制(比如,10用A表示,等等)。

 

2分析

首先要知道十进制的数是怎样转化为R进制的,然后再来考虑程序语言的实现。十进制的数转成二进制,最常用的方法,是除R取余法,将十进制的数n除以R取其余数,这里得到的余数是R进制数的最后一位。比如:7转化为2进制,先用7%2得到的是1,这里的1是转化后的二进制数的最后一位再令n=n/R,即为除得的整数结果(这里的n需要大于0,因为后续会产生重复的操作),同上例n=7/2=3;再用上述方法将3%2=1作为2进制数的倒数第二位。以此类推,2进制数的倒数第三位等于3/2%2=1;这时n=0,循环到此终止,二进制的数为111(注意是从第1位读到最后一位),即,代码实现时需要逆序输出(这里用数组来存取每一个余数)。逆序输出时,若R进制的数共有X位,令n=X-1;n往下移动一位一直到n=0,对数组进行输出。for循环可以实现。到此一个十进制的数转化成10进制以内任意R进制功能就实现了。

然后考虑11到16进制的转化,由于有了字母的引入。不能直接对于数组进行直接的输出。可以使用switch case 或者是if语句。倒顺序的每次判断均输出一个结果,输出结束要加上\n换行。

要对于0以及负数的单独判断。负数先转换为正数,按以上的方法输出后,再加上一个符号位(这里的符号位要在最开始输出);0则是直接等于0;

 

 

3源代码

#include<stdio.h>

int main()

{

    long n;

    int a[1000],b,i,j,r;

    while (scanf("%ld%d",&n,&r)!=EOF)

    {

                   i=0;

        if(n<0){n=-n;printf("-");}//对于负数,事先完成取正的转化,并在输出的最开始加上符号位

        if(n==0)

                   printf("0");//对于0,则是直接输出0

        while(n>0)

        {

            b=n%r;

            a[i++]=b;

            n=n/r;

        }        //将R进制的数字按照逆序依次存储到a数组中,注意在a数组中他们是按照顺序存储的,最后一位R进制数在第一位,以此类推

                   i=i-1;//i移动到数组的最后一位下标(实际是R进制的第一位数)

        for(j=i;j>=0;j--)

        {

          switch(a[j])

                     {  

                            case 10:printf("A");break;

                            case 11:printf("B");break;

                            case 12:printf("C");break;

                            case 13:printf("D");break;

                            case 14:printf("E");break;

                            case 15:printf("F");break;

                            default :printf("%d",a[j]);

                     }

                   }                                    //对超过10 的数进行判断,解释如上

         /*

             if(a[j]==10) printf("A");

            else if(a[j]==11)  printf("B");

            else if(a[j]==12)  printf("C");

            else if(a[j]==13)  printf("D");

            else if(a[j]==14)  printf("E");

            else if(a[j]==15)  printf("F");

            else printf("%d",a[j]);

                 //这里有两种方法都可以完成

         */

        printf("\n");

    }

    return 0;

} //程序结束,完成。

4总结

这个题的关键在于细分几种情况,并熟悉应用逆序输出进而编程。

十四

1题目简述

输入n(n<=100)个整数,按照绝对值从大到小排序后输出。题目保证对于每一个测试实例,所有的数的绝对值都不相等。

2分析

可以用结构体做,结构体中两个数:一个是输入的数的绝对值,用来排序用;另一个是原来的数,用来输出时用;在输入时简单控制下即可做到。
还要注意的是怎么给结构体中的数进行排序。

3源代码

 

#include <iostream>

#include <cstring>

#include <algorithm>

using namespace std;

const int N=105 ;

typedef struct same

{

    int a;

    int b;

}same;

int  cmp(same x,same y)        //对于结构体中的元素进行排序应注意要自己写函数!

{

    return x.a>y.a;

}

int main()

{

    same v[N];

    int n,i;

    while(cin>>n&&n)

    {

        memset(v,0,sizeof(v));

        for(i=0;i<n;i++)

        {

            cin>>v[i].a;

            v[i].b=v[i].a;

            if(v[i].a<0)

            {

                v[i].a=-v[i].a;

            }

        }

        sort(v,v+n,cmp);

        for(i=0;i<n-1;i++)

        {

            cout<<v[i].b<<" ";

        }

        cout<<v[n-1].b<<endl;

    }

    return 0;

}

4总结

这个题利用结构体来编程。排序的时候要小心

十五

1题目简述

A和B 都是由3个整数组成,分别表示时分秒,比如,假设A为34 45 56,就表示A所表示的时间是34小时 45分钟 56秒。输入数据有多行组成,首先是一个整数N,表示测试实例的个数,然后是N行数据,每行有6个整数AH,AM,AS,BH,BM,BS,分别表示时间A和B所对应的时分秒。题目保证所有的数据合法。对于每个测试实例,输出A+B,每个输出结果也是由时分秒3部分组成,同时也要满足时间的规则(即:分和秒的取值范围在0~59),每个输出占一行,并且所有的部分都可以用32位整数表示。

 

2分析

A+B此类问题是进位的问题,就本题而言,把握好进位的顺序就好,记得把秒分的60进制加上并且不要漏加上一次已经进位的,且要把进位的变化写到循环之中。

3源代码

#include<iostream>
using namespace std;

int main()
{
    int N,AH,AM,AS,BH,BM,BS;
    cin>>N;
    while(N)
    {
        cin>>AH>>AM>>AS>>BH>>BM>>BS;
        int H=0,M=0,S=0;                                  //
每次输入都要重新把H,M,S归零

        if(AS+BS>=60)
        {
            S=AS+BS-60;
            M=M+1;
        }
        else S=AS+BS;

        if(AM+BM>=60)
        {
            M=AM+BM-60+M;                               //
记得加之前可能已经进位的分钟
            H+=1;
        }
        else M=AM+BM+M;

        H=AH+BH+H;                                        //记得加之前可能已经进位的小时

        cout<<H<<" "<<M<<" "<<S<<endl;
        N--;
    }
    return 0;
}

 

 

4总结

这道题的关键是把握好进位问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值