《c++程序设计》课程设计报告
班级:数学2班 学号:2018212776
报告人姓名:刘涵
实验地点:山东农业大学东校机房411
完成起止时间:2019.1.2---2019.1.4
☆一
一,题意:
判断在给定的范围内是否存在水仙花数
二,题解:
首先题目要求输出多组数据,第二依据要求可利用取余和除法求出每个位数上的数,然后带入公式,最后在范围内如果符合则输出水仙花数,否则输出no。
三,原码:
#include
using namespace std;
#include
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<
else if(a>1){cout<<" "<
}
}
if(a==1)
cout<<"no";
cout< } } 四,注意事项:①输入范围内无水仙花数时的处理,可利用一个变量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 #include 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"< else cout<<"Sorry"< } } 注意事项: ①素数的判断:若从2到sqrt(t)-1的数均不可整除t,那t即为素数 ☆三 题意: 计算特殊多项式之和 题解: 相加的思想很简单,但细节很重要 原码: #include #include using namespace std; #include 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 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< else {if(i==1) cout< else if(i!=1) cout<<" "< } }s=0; if(n%m!=0) {for(i=(n-n%m+1);i<=n;i++) {s+=2*i;} cout< } cout< } } 注意事项: ①利用i j实现对前n/m个m项求平均值时,注意起始与终止值 ②偶数列的表示 {x+=(2*j);} ③x,y变量要定义为double ☆五 题意: 将输入的数按绝对值从小到大的顺序输出 题解: 依次通过两两比较将绝对值小的数往后放 原码: #include using namespace std; #include int main() { int n,i,j,t,a[105]; while(cin>>n) { if(n==0) break; else { for(i=0;i {cin>>a[i];} for(j=1;j { for(i=0;i<(n-j);i++) { if(abs(a[i]) {swap(a[i],a[i+1]);} } } for(i=0;i {cout<
cout<
} } return 0; } 注意事项: ①swap的使用,简化程序 ②i与j的配合,使得每两个数进行比较 ③最后一个输出的值后不要有空格 ④abs为整数取绝对值,可对应cstdlib ☆六 题意: 将一个数插入有序数列 题解:首先考虑特殊情况,如果x小于a[i],那么即令a[n]每个向后退一格,然后再表示普通情况,大于x的a[n]每个向后退一格 原码: #include 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 {cin>>a[i];} if(m
{ 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 {cout<
cout<
}cout< } } 注意事项:①将大于x的a[n]赋值给a[n+1],会出错;故可让j从n开始,向前赋值,从而避免出错 ②最后一项后无空格 ☆七 题意: 杭电老师发工资 题解: 按可使给每个老师的工资均无需找零,且所发张数最少,应从面额最大的100开始整除工资数,再取余,用50除于余额,依次向下进行 原码: #include 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 { cin>>a[i]; } h=0; for(i=0;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< } } } 注意事项:①只要细心输入整除及取余即可 ☆八 题意: 两个时间的相加 题解: 运用好选择结构,从秒开始相加,同时注意每到六十便向上一位进一 原码: #include using namespace std; int main() { double AH,AM,AS,BH,BM,BS,N,i; cin>>N; for(i=0;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)< else cout<<(AH+BH)<<" "<<(AM+BM+1)<<" "<<(AS+BS-60)< } else { if((AM+BM)>59) cout<<(AH+BH+1)<<" "< else cout< } } } ☆九 题意: 求手机号的短号 题解: 利用整除取余获得手机号的后五位,然后加上600000 原码: #include #include using namespace std; int main() { int N,i,y; long long int a[201]; cin>>N; for(i=0;i {cin>>a[i];} for(i=0;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< } } 注意事项:值得注意的是long long int的使用,很容易让人忽略,而若不注意,则会出现乱输出 ☆十 题意:排除不吉利数字 题解:将含有4,62的号码剔除,通过取余判断每一位是否为4,或每两位是否为62,另外在本题中我应用了预处理的方法,有些暴力但因为在时间限制内,也十分管用,就是略显麻烦。其实最好令i从n到m循环,使程序更简洁 原码: #include 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])< }} 注意事项:对含有4或 62的数做假循环t+=0;这样可排除使用该条件的真循环出现重复计数 ☆十一 题意: 判断给定的n m是否分别为两数之和,两数之积 题解: 原本想通过判断if(i+j==n&&i*j==m)解决,可这样会Output limited exceeded,也就是说有可能排除不了多余情况的输出。故我通过解两元方程的方法,将循环减少一重,且通过变量a的值控制单次输出,简化了程序。 原码: #include #include 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"< } if(a==0) cout<<"No"< } }} 注意事项:if(i*i-i*n+m==0&&a==0)中a的使用,避免了不必要输出 ☆十二 题意: 判断是否为SKY数 题解: 根据进制转化,将数值除16或12取余,再令其余数除16或12取余,依次向下进行 原码: #include #include 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< else cout< } } 注意事项:将t=k=0;放在else条件内,使其尽量挨着与其相关的执行语句,避免出现乱输入 ☆十三 题意: A的B次方 题解:显然若1000的1000次方连long long int也无效了,于是想到其实A的B次方的后三位与前边的几位数并无关,这样问题就简化了 原码: #include #include 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=(t*A)%1000;的使用让程序简化 ☆十四 题意: M阶台阶的走法 题解:与前面一题,和后边一题类似,推导公式 原码: #include 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];