课程设计报告

          《c++程序设计》课程设计报告

班级:数学2班                                      学号:2018212776

报告人姓名:刘涵

实验地点:山东农业大学东校机房411

完成起止时间:2019.1.2---2019.1.4

                     ☆一

一,题意:

判断在给定的范围内是否存在水仙花数

二,题解:

首先题目要求输出多组数据,第二依据要求可利用取余和除法求出每个位数上的数,然后带入公式,最后在范围内如果符合则输出水仙花数,否则输出no。

三,原码:     

             #include<iostream>

             using namespace std;

         #include<math.h>

              int main()

           { int m,n,l,g,k,i,a;

           while(cin>>m>>n)

            { a=1;

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

           { l=i%10;

            g=i/10%10;

            k=i/100;

           if(i==pow(l,3)+pow(k,3)+pow(g,3))

           { if(a==1){cout<<i;a++;}

           else if(a>1){cout<<" "<<i;}

           } 

          }

            if(a==1)

            cout<<"no";

            cout<<endl;

            }      

            }

四,注意事项:①输入范围内无水仙花数时的处理,可利用一个变量a,初值为一,如存在水仙花数,则加一,最终通过判断a值,来表示此情况是否存在。

②可利用pow简化程序

③最后一个空格的输出:由于平台的检查输出是否正确,都是把输出内容放在文件里,然后以字符串的形式去和正确答案做对比,一直读到文件的末尾EOF,这个时候末尾多余的那些看不见的字符就会被读出来,然后发现输出和正确答案不同,得出PE!!!

④if else if 的使用

if(条件..1){

     要执行的语句;

}

if(条件..2){

   要执行的语句

}

双if是每一个if都会进行判断,依次对if进行判断,互相之间不会影响;

if(条件..1){

    执行的语句

}else if(条件..2){

   执行的语句

}

这个if和else if 之间是有联系的,当不满足if中的条件的时候,就会去执行else if ,如果if中的条件已经满足了,就不会去判断else if中的条件了

                   ☆二

题意:

判断表达式的值是否都为素数。

题解:

首先输入多组样例,再带入公式计算结果,接着判断结果是否为素数,最后利用变量a的值判断是否范围内的值均为素数。

原码:

 #include<iostream>

#include<math.h>

using namespace std;

int main()

{ int x,y,n,i,a,t;

    while(cin>>x>>y)

 { if(x==0&&y==0)

    break;

   else

  { a=0;

    for(n=x;n<=y;n++)

   {t=n*n+n+41;

   for(i=2;i<=sqrt(t);i++)

   {if(t%i==0)

     a++;

   }

   }

  } if(a==0)

   cout<<"OK"<<endl;

   else

   cout<<"Sorry"<<endl;

 }

}

注意事项:

①素数的判断:若从2到sqrt(t)-1的数均不可整除t,那t即为素数

                  ☆三

题意:

计算特殊多项式之和

题解:

相加的思想很简单,但细节很重要

原码:

#include<stdio.h>

#include<iostream>

using namespace std;

#include<math.h>

int main()

{ int m,n,i,j;

    double s;

    cin>>m;

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

    {cin>>n;s=0;

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

    {s+=1/(j*1.0)*(pow(-1,j+1));}

    printf("%.2lf\n",s);

    }

}

注意事项:

①当1/j时,要对j先乘于一个1.0,以实现整型数到实型数的变换

②对多项式每一项前正负号的描述,利用pow(-1,j+1)

               ☆四

题意:

求一个平均值序列,分两种情形

题解:

分两步做,先对前几项,符合可被m整除的,控制每m项求一个平均值,最后对有余项取平均值

原码:

#include<iostream>

using namespace std;

int main()

{ int s,i,j,n,m;

    double y,x;

    while(cin>>n>>m)

 {

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

    {x=y=0;

    for(j=((i-1)*m+1);j<=((i-1)*m+m);j++)

    {x+=(2*j);}

    y=x*1.0/m;

    if(n%m!=0)

    cout<<y<<" ";

    else

    {if(i==1) 

     cout<<y;

     else if(i!=1)

     cout<<" "<<y;

    }

    }s=0;

    if(n%m!=0)

   {for(i=(n-n%m+1);i<=n;i++)

    {s+=2*i;}

    cout<<s;

   }

   cout<<endl;

 }

}    

注意事项:

①利用i j实现对前n/m个m项求平均值时,注意起始与终止值

②偶数列的表示 {x+=(2*j);}

③x,y变量要定义为double

                    ☆五

题意:

将输入的数按绝对值从小到大的顺序输出

题解:

依次通过两两比较将绝对值小的数往后放

原码:

#include<iostream>

using namespace std;

#include<cmath>

int main()

{

    int n,i,j,t,a[105];

    while(cin>>n)

{ if(n==0)

    break;

    else

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

    {cin>>a[i];}

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

{ for(i=0;i<(n-j);i++)

{ if(abs(a[i])<abs(a[i+1]))

    {swap(a[i],a[i+1]);}

}

}

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

    {cout<<a[i]<<" ";}

   cout<<a[n-1]<<endl;

}

} return 0;

}

注意事项:

①swap的使用,简化程序

②i与j的配合,使得每两个数进行比较

③最后一个输出的值后不要有空格

④abs为整数取绝对值,可对应cstdlib

                 ☆六

题意:

将一个数插入有序数列

题解:首先考虑特殊情况,如果x小于a[i],那么即令a[n]每个向后退一格,然后再表示普通情况,大于x的a[n]每个向后退一格

原码:

#include<iostream>

using namespace std;

int main()

{

    int n,l,i,j,m,a[105];

  while(cin>>n>>m)

  { if(m==0&&n==0)

       exit(0);

    else 

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

     {cin>>a[i];}

     if(m<a[0])

     {

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

     {a[i]=a[i-1];}

      a[0]=m;

     }

      else

    {for(i=n-1;i>=0;i--)

    {if(m>a[i])

     {l=(i+1);break;}

    }

    for(j=n;j>l;j--)

    {a[j]=a[j-1];}

     a[l]=m;

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

    {cout<<a[i]<<" ";}

         cout<<a[n];

    }cout<<endl;

}

}

注意事项:①将大于x的a[n]赋值给a[n+1],会出错;故可让j从n开始,向前赋值,从而避免出错

②最后一项后无空格

                    ☆七

题意:

杭电老师发工资

题解:

按可使给每个老师的工资均无需找零,且所发张数最少,应从面额最大的100开始整除工资数,再取余,用50除于余额,依次向下进行

原码:

#include<iostream>

using namespace std;

int main()

{

    int n,a[100],x,t,f,g,y,l,k,e,h,i;

    while(cin>>n)

    {

        if(n==0)

        break;

        else

        {

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

            {

                cin>>a[i];

            } h=0;

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

            {t=a[i]/100;

            f=a[i]%100/50;

            g=a[i]%100%50/10;

            y=a[i]%100%50%10/5;

            l=a[i]%100%50%10%5/2;

            k=a[i]%100%50%10%5%2;

            e=t+f+g+y+l+k;

            h=h+e;

            }

            cout<<h<<endl;

        }

    }

}

注意事项:①只要细心输入整除及取余即可

                     ☆八

题意:

两个时间的相加

题解:

运用好选择结构,从秒开始相加,同时注意每到六十便向上一位进一

原码:

#include<iostream>

using namespace std;

int main()

{

      double AH,AM,AS,BH,BM,BS,N,i;

        cin>>N;

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

        {cin>>AH>>AM>>AS>>BH>>BM>>BS;

            if((AS+BS)>59)

          {

              if((AM+BM+1)>59)

              cout<<(AH+BH+1)<<" "<<(AM+BM-59)<<" "<<(AS+BS-60)<<endl;

              else

              cout<<(AH+BH)<<" "<<(AM+BM+1)<<" "<<(AS+BS-60)<<endl;

          }

            else

          { if((AM+BM)>59)

              cout<<(AH+BH+1)<<" "<<AM+BM-60<<" "<<AS+BS<<endl;

              else

              cout<<AH+BH<<" "<<AM+BM<<" "<<AS+BS<<endl;

          }

        }

}

          ☆九

题意:

求手机号的短号

题解:

利用整除取余获得手机号的后五位,然后加上600000

原码:

#include<iostream>

#include<math.h>

using namespace std;

int main()

{ int N,i,y;

 long long int a[201];

 cin>>N;

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

 {cin>>a[i];}

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

 {y=6*pow(10,5)+a[i]%10+((a[i]/10)%10)*10+((a[i]/100)%10)*100+((a[i]/1000)%10)*1000+((a[i]/10000)%10)*10000;

  cout<<y<<endl;

 }

}

注意事项:值得注意的是long long int的使用,很容易让人忽略,而若不注意,则会出现乱输出

            ☆十

题意:排除不吉利数字

题解:将含有4,62的号码剔除,通过取余判断每一位是否为4,或每两位是否为62,另外在本题中我应用了预处理的方法,有些暴力但因为在时间限制内,也十分管用,就是略显麻烦。其实最好令i从n到m循环,使程序更简洁

原码:

#include<iostream>

using namespace std;

int a[1000000]={0};

int main()

{

    int n,m,i,t=0;

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

        {

            if(i%10==4||i/10%10==4||i/100%10==4||i/1000%10==4||i/10000%10==4||i/100000%10==4)

            t+=0;

            else if(i%100==62||i/10%100==62||i/100%100==62||i/1000%100==62||i/100000%1000==62)

            t+=0;

            else

            t++;

            a[i]=a[i]+t;

        }

       while (cin>>n>>m)

{ if(n==0&&m==0)

       break;

       else

      {cout<<(a[m]-a[n-1])<<endl;}

}}

注意事项:对含有4或 62的数做假循环t+=0;这样可排除使用该条件的真循环出现重复计数

                 ☆十一

题意:

判断给定的n m是否分别为两数之和,两数之积

题解:

原本想通过判断if(i+j==n&&i*j==m)解决,可这样会Output limited exceeded,也就是说有可能排除不了多余情况的输出。故我通过解两元方程的方法,将循环减少一重,且通过变量a的值控制单次输出,简化了程序。

原码:

#include<iostream>

#include<math.h>

using namespace std;

int main()

{

    int n,m,i,j,a;

    while(cin>>n>>m)

  {if(n==0&&m==0)

      break;

   else

   { a=0;

       for(i=-99;i<100;i++)

      {if(i*i-i*n+m==0&&a==0)

            {a++;cout<<"Yes"<<endl;}

      }

      if(a==0)

      cout<<"No"<<endl;

   }

}}

注意事项:if(i*i-i*n+m==0&&a==0)中a的使用,避免了不必要输出

               ☆十二

题意:

判断是否为SKY数

题解:

根据进制转化,将数值除16或12取余,再令其余数除16或12取余,依次向下进行

原码:

#include<iostream>

#include<math.h>

using namespace std;

int main()

{

    int n,t,k,s,d,g;

    while(cin>>n)

    { d=n;g=n;

        if(n==0) break;

        else

        {

            s=n%10+n/10%10+n/100%10+n/1000;

            t=k=0;

            while(d!=0)

            {

                t+=d%16;

                d=d/16;

            }

             while(g!=0)

            {

                k+=g%12;

                g=g/12;

            }

          } if(s==t&&s==k)

            cout<<n<<" is a Sky Number."<<endl;

            else

            cout<<n<<" is not a Sky Number."<<endl;

        

    }

}

注意事项:将t=k=0;放在else条件内,使其尽量挨着与其相关的执行语句,避免出现乱输入

                       ☆十三

题意:

A的B次方

题解:显然若1000的1000次方连long long int也无效了,于是想到其实A的B次方的后三位与前边的几位数并无关,这样问题就简化了

原码:

#include<iostream>

#include<math.h>

using namespace std;

int main()

{ int A,B,t,i;

    while(cin>>A>>B)

    {

        if(A==0&&B==0)

        break;

        else

        { t=1;

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

{ t=(t*A)%1000;

}

       } cout<<t<<endl;

    }

}

注意事项: t=(t*A)%1000;的使用让程序简化

                   ☆十四

      题意:

M阶台阶的走法

题解:与前面一题,和后边一题类似,推导公式

原码:

#include<iostream>

using namespace std;

int main()

{ int N,M,i,k,a[42];

    cin>>N;

    for(k=1;k<=N;k++)

    {cin>>M;

     a[2]=1;

     a[3]=2;

     a[1]=0;

     if(M>3)

    {for(i=4;i<=M;i++)

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

    } cout<<a[M]<<endl;

    }

}

注意事项:①初始时是在第一阶

②最后输出a[M],输出a[i]无结果

③前几阶无规律的单独列出

              ☆十五

题意:

计算集合A-B

题解:

即比较A与B中的元素,把A中含有的B中也有的元素去掉,我采用将这样的A中的元素付给他一个超范围值,没想到其他方法,但这样却十分省时间

原码:

#include<iostream>

#include<algorithm>

#include<cmath>

using namespace std;

int main()

{ int n,m,i,j,a[101],b[101],s;

   while(cin>>n>>m)

 {

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

    exit(0);

    else

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

     cin>>a[i];

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

     cin>>b[j];

    sort(a,a+n);s=0;

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

    {for(j=0;j<m;j++)

     { if(a[i]==b[j])

     {

       a[i]=pow(10,8);

       s++;

     }

     }if(a[i]!=pow(10,8))

      cout<<a[i]<<" ";

    }

    if(s==n)

    cout<<"NULL";

  }cout<<endl;

 }

}

注意事项:超范围值一定要真的超范围

总结:

每个题都不能轻易判断其简单或困难,或者说无论题难题简单,都应认真应对,会做的要做对,不会的不到最后绝不放弃。虽然课程结束了,自己也没做的多好,但通过本次活动,仍有很多收获,比如凡事需细心,不要少做,不要只顾头不顾尾,像是好多题中最后一个空格的不必要输出问题。还有,当周围有人在躁动,自己也要学会冷静下来,这对考试时是有很大帮助的,这也是我一直需要改变的,我想通过这次活动,我改变了不少。

                 

                    

猜你喜欢

转载自blog.csdn.net/weixin_43240899/article/details/85853765