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