1. 程式人生 > >課程設計報告

課程設計報告

          《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;

 }

}

 

注意事項:超範圍值一定要真的超範圍

 

 

總結:

每個題都不能輕易判斷其簡單或困難,或者說無論題難題簡單,都應認真應對,會做的要做對,不會的不到最後絕不放棄。雖然課程結束了,自己也沒做的多好,但通過本次活動,仍有很多收穫,比如凡事需細心,不要少做,不要只顧頭不顧尾,像是好多題中最後一個空格的不必要輸出問題。還有,當週圍有人在躁動,自己也要學會冷靜下來,這對考試時是有很大幫助的,這也是我一直需要改變的,我想通過這次活動,我改變了不少。