2018212770数学白世纪 期末程序设计

Problem 1

  1. 题目大意:“水仙花数”是指一个三位数,它的各位数字的立方和等于其本身,给出一个区间,找出这个区间内的所有水仙花数,如果没有,输出“no”。
  2. 解题思路:先把这个三位数的各位数字分离出来,然后通过一个条件语句判断是否为水仙花数,把每一个水仙花数存在一个数组里,最后输出。
  3. 解题细节:此题思路较清晰,但需要注意输出的最后一个水仙花数后面没有空格,所以应该注意控制空格与换行,否则,容易出现PE格式错误。
  4. 原码:
            #include<iostream>
    using namespace std;
    int main()
    {
        int n,m,i,t,s,a,j;
        int o[1000];
        while(cin>>n>>m)
        {
            int w=0;
            for(i=n;i<=m;i++)
            {
                t=i/100;//百位分离
                s=i%10;//个位分离
                a=i/10%10;//十位分离
                if(i==t*t*t+s*s*s+a*a*a)
                {
                    o[w]=i;//存到数组里
                    w++;
                    }
                    }
                 
                 if(w==0)
                 cout<<"no"<<endl;//没有水仙花数,输出no
                 else
                {
                    for(j=0;j<w;j++)
                    {
                        cout<<o[j];
                        if(j<w-1)
                        cout<<" ";//控制最后一个数后面没有空格
                        }
                        cout<<endl;
                        
                          }
                            }
                
                        
    return 0;
                

}

Problem 2

  1. 题目大意:有一个长度为n(n<=100)的数列,该数列定义为从2开始的递增有序偶数,现在要求你按照顺序每m个数求出一个平均值,如果最后不足m个,则以实际数量求平均值。编程输出该平均值序列。
  2. 解题思路:从2开始每次加2循环n次,将每一次循环的和存在sum里,用一个t=0记录次数,当t=m时,输出平均值,再令t=0,注意最后不足m个时的情况。
  3. 原码:
            #include<iostream>
    using namespace std;
    int main()
    {
        int n,m,i,sum,num;
        while(cin>>n>>m)
        {
            num=0;sum=0;//赋值为0
            for(i=2;i<=n*2;i=i+2)
            {
               sum+=i;//将每m个数加起来
               num++;
               if(num==m&&i!=n*2)//控制输出条件,考虑最后一个数后面的空格
               {
               cout<<sum/num<<" ";
               num=0;//再次赋值为0,进行新一轮的循环
               sum=0;
               }
            }
        cout<<sum/num;
        cout<<endl;
        }
    }
    Problem 3
  1. 题目大意:输入n(n<=100)个整数,按照绝对值从大到小排序后输出。题目保证对于每一个测试实例,所有的数的绝对值都不相等。
  2. 解题思路:先将这n个数存到一个原数组里,然后将这n个数的绝对值存到另外一个数组里,用sort函数将绝对值数组排序,再利用一个嵌套循环,将两个数组进行匹配,输出原数组的数,此处注意控制空格。
  3. 原码:
            #include<iostream>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    int main()
    {
        int a[1000],b[1000];
        int n,i,j,x;
        while(cin>>n)
        {
            if(n==0)
            return 0;
           for(i=1;i<=n;i++)
          {
     
              cin>>a[i];//将原数存到一个数组里
            }
            for(i=1;i<=n;i++)
            {
               x=fabs(a[i]);//将绝对值存到一个数组里
               b[i]=x;
            }
            sort(b+1,b+n+1);
            for(i=n;i>=1;i--)
            {
                for(j=1;j<=n;j++)
                {
                    if(b[i]==fabs(a[j])&&i==1)//进行匹配,并控制最后一个数后面没有空格
                    {
                        cout<<a[j];
                    }
                    if(b[i]==fabs(a[j])&&i!=1)
                    {
                        cout<<a[j]<<" ";
                    }
     
                }
            }
            cout<<endl;
     
        }
    return 0;
    }
    Problem 4
    1.题目大意:已知n个老师每个人的工资,人民币有100,50,10,5,2和1元6种情况,为了不找零求至少需要准备的人民币张数。
    2.解题思路:先将100,50,10,5,2和1元存到一个数组里,然后再将每个老师的工资存在另一个数组里,再利用一个嵌套循环,将每个老师的工资与这6种面值的纸币从大到小相减,如果大于0,则代表需要这种类型纸币1张,将相减之后的数继续与较小的纸币相减,直到最后小于0,并记录次数。
    3.原码:
             #include<iostream>
    int a[6]={100,50,10,5,2,1};//将6种面值的纸币存入这个数组
    int b[1000];
    using namespace std;
    int main()
    {
     
      int n,i,j,s=0;
      while(cin>>n)
      {
          if(n==0)
          return 0;
        for(i=0;i<n;i++)
        {
          cin>>b[i];//将每个教师的工资存入数组
        }
        for(i=0;i<n;i++)
        {
         for(j=0;j<6;j++)
          {
             while(b[i]-a[j]>=0)//从大面值到小面值依次判断
              {
                 s++;//记录需要纸币的张数
                 b[i]=b[i]-a[j];
                }
         }
      }
      cout<<s<<endl;
    s=0;
    }
    }
    Problem 4
  1. 题目大意:“回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。请写一个程序判断读入的字符串是否是“回文”。
  2. 解题思路:先定义一个字符数组,然后将它输入,利用strlen求出字符串长度,再通过循环字符长度的次数,将输入的字符串倒着赋给另一个数组,最后判断两个数组的元素是否都一样,如果一样,则是字符串。
  3. 原码:
             #include<stdio.h>
    #include<string.h>
    #include<iostream>
    using namespace std;
    int main()
    {
         int n;
        while (cin>>n)
        {
            int i,length,count;
            char a[1000],b[1000];
            while (n--)
            {
                count = 0;
               scanf("%s",a);
                length = strlen(a);//算出字符串的长度
                for (i=0;i<length;i++)
                b[i] = a[length-1-i];//将该字符串倒着赋给另外一个新的数组
                for (i=0;i<length;i++)
                    if (b[i] == a[i])//判断该字符串正着倒着是否都一样
                        count++;//判断相等元素的个数;
                if (count == length)
                    cout<<"yes"<<endl;
                else
                    cout<<"no"<<endl;
            }
     
        }
        return 0;

 

}

Problem 5

1题目大意:输入一个十进制数N,将它转换成R进制数输出。

2解题思路: 此题应当熟悉进制的转化运算,就是将N%R=t,然后N%(N/R)。这样不断的求余,然后将余数倒着排列就是该进制下的数。应当注意的是,当这个数是负数时,应当先输出一个负号,然后将整数带入下面的程序。然后就是进制的运算,注意如果余数大于等于10时,应当用A,B,….F代替。

3原码:

    #include<bits/stdc++.h>

using namespace std;

int main()

{

    int a[1000];

     int m,r,t,j,i=0;

     while(cin>>m>>r)

     {

         i=0;

         if(m<0)

         {

             cout<<'-';//先输出负号

             m=-m;//将负数的绝对值带入下面的程序

            }

         while(m>0)

         {

             t=m%r;

           a[i]=t;//将余数存入数组中

           i++;//记录数组的长度

           m=m/r;

         }

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

        {

            if(a[j]>=10)

            cout<<char('A'+a[j]-10);//控制当余数为大于等于10时输出字母

            else

            cout<<a[j];

        }

        cout<<endl;

 

     }

 

 

 

}

Problem 6

  1. 题目大意:给定两个集合A与B,输出A集合有的元素但B集合里面没有的元素,如果不存在,则输出“Null”。
  2. 解题思路:先将A的集合存到一个数组里,然后将B集合存到另外一个数组里,再利用一个嵌套循环进行A集合与B集合元素比较,从A数组里的第一个元素与B集合的任一元素比较是否相等,将不相等的元素存到C这个数组里,最后利用sort函数进行排序,然后输出。
  3. 原码:
            #include<iostream>
    #include<algorithm>
    using namespace std;
    int main()
    {
        int a[1000],b[1000],c[1000];
        int n,m,i,j,k,t=0;
        while(cin>>n>>m)
        {    k=0;
            if(n==0&&m==0)
            return 0;
            for(i=0;i<n;i++)
            cin>>a[i];//存入A集合
            for(i=0;i<m;i++)
            cin>>b[i];//存入B集合
            for(i=0;i<n;i++)
            {     t=0;
                for(j=0;j<m;j++)
                {
                    if(a[i]==b[j])//将A集合的数组里的每个元素与B集合的全部元素挨个比较
                    t++;//判断相等元素的个数
                }
                if(t==0)
                {
                   c[k]=a[i];//将A-B的元素存入C这个数组
                   k++;
                }
            }
                if(k==0)
                cout<<"NULL";
               else
                {
                    sort(c,c+k);//从小到大排序
                    for(i=0;i<k;i++)
                    cout<<c[i]<<" ";
                }
                cout<<endl;
        }
    return 0;
    }

         Problem 7

  1. 题目大意:训练的蜜蜂只能爬向右侧相邻的蜂房,不能反向  。请编程计算蜜蜂从蜂房a爬到蜂房b的可能路线数。
    其中,蜂房的结构如下所示。
      

2解题思路:1→2 1步 1→3 2步 1→4  3步 1→5  5步  1→6 8步由此可以发现递推规律,可以先给a【1】a【2】赋值,然后根据递推规律给a数组里每个位置赋值,特别注意!!a数组的范围较大,应当用long long int;

3原码:#include<iostream>

using namespace std;

int main()

{

    long long int c[50];

   int a,b,i,n;

   c[1]=1;c[2]=2;//初始化两个位置

   for(i=3;i<=50;i++)

   {

       c[i]=c[i-1]+c[i-2];//给每个位置赋值

   }

   while(cin>>n)

   {

       while(n--)

       {

           cin>>a>>b;

           cout<<c[b-a];/输出对应差值的的步数

           cout<<endl;

       }

 

   }

}

Problem 8

  1. 题目大意:有如下方程:Ai = (Ai-1 + Ai+1)/2 - Ci (i = 1, 2, 3, .... n).
    若给出A0, An+1, 和 C1, C2, .....Cn.请编程计算A1 = ?

2.解题思路:   A1 + A2 + A3 + ... + An = (A0 + A1 + 2*A2 + 2*A3 + .. .+ 2*An-1 + An + An+1) / 2  - c1 - c2 - c3 - .... - cn

 

==>     A1 + An = A0 + An+1 - 2(c1 + c2 + c3 + ... +cn)

 

A1 + A1 = A0 + A2 - 2*c1

 

A1 + A2 = A0 + A3 - 2(c1 + c2)

 

...................

 

(n + 1)*A1 = n*A0 + An+1  -  2(n*c1 + (n-1)*c2 + (n-2)*c3 +......+ cn)

3.原码: 

 

          #include<stdio.h>

#define N 3001

int main()

{

    int n;

    float a, b;

    float c[N];

    float sum;

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

    {

        sum = 0;

        scanf("%f%f", &a, &b);

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

        {

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

            c[i] *= (n-i+1);

            sum += c[i];

        }

 

        sum *= 2;

 

        float ans = (n*a + b - sum) / (n+1);

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

    }

}

Problem 9

  1. 题目大意:不吉利的数字为所有含有4或62的号码。给定一个区间(n,m),输出这个区间内的吉利数字的个数。
  2. 解题思路:因为直到了n,m的范围在(0,1000000),所以考虑运用暴力求解法来解决,首先在这个范围内通过算法寻找含有4或62的数字并将其存到数组a中并都赋初值为1,然后存储完毕后,输入n,m。这时只需判断n,m范围内的不是1的个数就可以了。
  3. 原码: 
             #include<cstdio>
    #include<iostream>
    using namespace std;
    int a[1000010];
    int main()
    {
        int i,l,r;
        for(i=1;i<1000000;i++)
        {
            int t=i;
            while(t>0)
            {
                if(t%10==4||t%100==62)//判断是否含有4与62
                    a[i]=1;//赋值为1
                t/=10;
            }
        }
        while(cin>>l>>r)
        {
            if(l==0&&r==0)
            return 0;
            int i,c=0;
            for(i=l;i<=r;i++)
            {
                if(a[i]!=1) //判断是否为吉利数字
                    c++;//判断吉利数字的个数
            }
            cout<<c<<endl;
        }
    }

Problem 10

 

1题目大意:母牛,他每年年初生一头小母牛,每头小母牛从第四个年头开始,每年年初也生一头小母牛,编程实现在第n年的时候,共有多少头母牛。

  1. 解题思路:这道题问第几年有几头牛,首先看输入输出,可以知道当年数小于等于4的时候,第几年就有几头牛,当n大于4的时候,这时候第一年出生的小母牛又可以生小牛了,也就是说要考虑到小牛是否可以生了。每年都有有a(n-1)头母牛,那么就要知道这一年出生的母牛有多少。第n-3年有多少头母牛,到了第n年这些牛都能生小牛了,因此出生数a(n-3。 从而今年的母牛数为a(n)=a(n-1)+a(n-3)。
  2. 原码:
            #include<iostream>
    using namespace std;
    int main()
    {
        int a[10000]={1,2,3};
        int n,i,t;
        while(cin>>n)
        {
            if(n==0)
            return 0;
            if(n<=3)
            {
                cout<<n<<endl;
                }
                else
                {
                    for(i=3;i<n;i++)
                    {
                        a[i]=a[i-1]+a[i-3];
                        }
                        t=n-1;
                        cout<<a[t]<<endl;
                        }
                        }
        return 0;
    }

Problem 11

  1. 题目大意:这次xhd面临的问题是这样的:在一个平面内有两个点,求两个点分别和原点的连线的夹角的大小。注:夹角的范围[0,180],两个点不会在圆心出现。
  2. 解题思路:这个题刚看到一脸懵,但仔细分析发现这个题运用中学时的向量公式就可以解决,先利用两点的向量之积等于两点的向量之模之积乘以cos a。
    然后求出cos a,然后利用arccos cos a 求出a,然后a乘以180/3.1415926,即为所求,切记保留2位小数。

3 原码:

          #include<bits/stdc++.h>

using namespace std;

int main()

{

    double a,b,c,d,x,P=3.1415926,q,t;

    int n;

   while(cin>>n)

   {

      while(n--)

      {

          cin>>a>>b>>c>>d;

          x=(a*c+b*d)/(sqrt(a*a+b*b)*sqrt(c*c+d*d));

          q=acos(x);

          t=q*(180/P);

          cout<<fixed<<setprecision(2)<<t;

     

      cout<<endl;}

   }

Problem 12

  1. 题目大意:一个整数,只知道前几位,不知道末二位,被另一个整数除尽了,求最后两位的数字。
  2. 解题思路:首先将n以100,然后进入循环,在(n*100,n*100+100)内进行循环,找出其中能整除m,的数存放到一个数组里。注意如果数组里的数小于10的话,需要先输出0,在输出这个个位数,并且注意空格
  3. 原码:
         

            #include<bits/stdc++.h>

using namespace std;

int p[100];

int main()

{

    int a,b,i,t,j,s,k=0;

    while(cin>>a>>b)

    {

       if(a==0&&b==0)

        return 0;

        t=a*100;

 

        for(i=t;i<t+100;i++)

        {

           if(i%b==0)

           {

               p[k]=i-t,k=k+1;

             }

        }

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

             {

                 if(p[j]<10&&j!=(k-1))

                 cout<<0<<p[j]<<' ';

                 else if(p[j]<10&&j==(k-1))

                 cout<<0<<p[j];

                 else if(p[j]>=10&&j!=(k-1))

                 cout<<p[j]<<' ';

                 else

                 cout<<p[j];

             }

             cout<<endl;

             memset(p,0,sizeof(p));k=0;

}    }

Problem 13

1.题目大意:一个偶数拆成两个不同素数的和,有几种拆法呢?

2解题思路:解决素数这种类型题目时,我喜欢用定义函数先写出判断是否为素数的函数,因为这可以让自己的思路更加清晰,然后从2到2/n内循环判断,注意是n/2,因为如果是n的话会多加一遍。

3解题细节:这个题刚开始定义函数时 判断素数循环应该小于n的1/2次方,如果小于n,则会超时!超时!

4代码:

 

          #include<bits/stdc++.h>

using namespace std;

int ss(int n)

{

    int i,k=0;

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

    {

        if(n%i==0)

        k++;

    }

    if(k==0)

    return 1;

    else

    return 0;

}

int main()

{

 

    int n,j,s=0;

    while(cin>>n)

{

    if(n==0)

    break;

    for(j=2;j<n/2;j++)

    {

       if(ss(j)==1&&ss(n-j)==1)

     s++;

    }

    cout<<s;

    s=0;

    cout<<endl;

 

}

return 0;

}

Problem 14

1题目大意:Sky从小喜欢奇特的东西,而且天生对数字特别敏感,一次偶然的机会,他发现了一个有趣的四位数2992,这个数,它的十进制数表示,其四位数字之和为2+9+9+2=22,它的十六进制数BB0,其四位数字之和也为22,同时它的十二进制数表示1894,其四位数字之和也为22,啊哈,真是巧啊。Sky非常喜欢这种四位数,由于他的发现,所以这里我们命名其为Sky数。但是要判断这样的数还是有点麻烦啊,那么现在请你帮忙来判断任何一个十进制的四位数,是不是Sky数吧。

2解题思路:这个题我的思路依然是应用函数直接计算他的十进制与12进制丶16进制的各位数字之和,最后判断他们之和是否相等,最后输出是否是sky数。

3 原码:#include<bits/stdc++.h>

using namespace std;

int bsj(int n,int r)

{

    int x,t,s=0;

    t=n;

    while(t>0)

    {

        x=t%r;

        t=t/r;

        s=s+x;

    }

    return s;

}

int main()

{

    int n,r;

    int bsj(int n,int r);

    while(cin>>n)

    {

        if(n==0)

        return 0;

        if(bsj(n,10)==bsj(n,12)&&bsj(n,10)==bsj(n,16))

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

        else

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

        cout<<endl;

    }

    return 0;

}

Problem 15

1 题目大意:有二个整数,它们加起来等于某个整数,乘起来又等于另一个整数,通过编程判断这种整数是否存在

2解题思路:    x + y = m
x * y = n

所以:
x * (m - x) = n
x^2 - m * x + n = 0

求解后:
x1 = (m + sqrt(m ^ 2 - 4n)) / 2和x2 = (m - sqrt(m ^ 2 - 4n)) / 2

因此只需要判断x1和x2是否整数就行了。

3原码:

       #include<bits/stdc++.h>

using namespace std;

int main()

{

    int n,m,t,num;

   while(cin>>n>>m,n!=0||m!=0){

        int num = n*n - 4*m;

        t = sqrt(num);

        if(t*t==num){

            cout<<"Yes"<<endl;

        }else{

            cout<<"No"<<endl;

        }

     }

 

 

}

总结:通过这三天呆在机房的上机实验,做程序设计,感觉我的c语言水平又上到了一个新的台阶,虽然有些问题在现在看来还是比较棘手,但我仍然获益匪浅,这两组程序设计大多数题目都是要用多组输入数据,因为这才符合实际需要,我学到了怎么样控制输入格式,比如说控制换行与空格输入,对正确的格式有了新的理解。这次课程设计中,我的收获还有就是学会了用流程图来表达自己的想法,并根据流程图来逐步实现程序的功能。开始的时候,我画流程图很是困难,需要一个多小时才能清楚的根据自己的想法画出图来,后来画多了,就更加了解它的功能,十分得心应手,能够比较快而准确的画出来。在这次课程设计中我还懂得了想学好C语言,交流是必须的,很多细节的错误或者算法上的小瑕疵往往是当局者迷旁观者清,这时候果断与身边人进行交流是明智的选择。而且在学习的过程中,同学之间相互交流学习心得可以快速学习,事半功倍。学习C语言就是要经过上机上机再上机,交流交流再交流。才能前后融会贯通,积累所应该掌握的知识。C语言是这样,其他语言也是这样,从基本抓起,多动手,多动脑,不懂就问,注意平时积累。虽然我的大学生涯中c语言要即将告一段落,但我仍会继续学习,继续进步!
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值