《c++程序设计》课程设计报告
班级:数学四班 学号:2018212721
报告人姓名:杜雨
实验地点:教学楼414
完成起始日期:2019/1/2—2019/1/5
一.第一套Problem B:
1.简要题意:输入n, m代表区间范围,输出区间内所有的水仙花数(“水仙花数”是指一个三位数,它的各位数字的立方和等于其本身),并且将数从大到小输出。如果给定的范围内不存在水仙花数,则输出no。
2.解题思路:1》先将给定区间数的个十百位分离,找出所有符合题意的数。2》将符合条件的数存入一数组中,按照条件输出。
3. #include<stdio.h>
int main()
{
int n,m,x=0,a[900],j=1;
while(scanf("%d %d",&n,&m)!=EOF)//将数据多组输入//
{
for(int i=n;i<=m;i++)
{
if(i==(i/100)*(i/100)*(i/100)+(i%10)*(i%10)*(i%10)+(i/10-(i/100)*10)*(i/10-(i/100)*10)*(i/10-(i/100)*10))//区间内水仙花数//
{
a[j]=i; j++;//将水仙花数存入数组//
}
else x=x+1;//设置标记变量//
}
if(x!=m-n+1)//表示区间内包含水仙花数//
{
for(int i=1;i<j-1;i++)
{
printf("%d ",a[i]);//前n-1个数有空格输出//
}
printf("%d",a[j-1]);//直接输出第n个数//
printf("\n");}
if(x==m-n+1) printf("no\n");//区间内不包含水仙花数//
x=0;//循环初始化//
for(int i=1;i<j;i++)
{
a[i]=0;
}
j=1;//循环初始化//
}
return 0;
}
二.第一套problemE
1.简要题意:多项式的描述如下:1 - 1/2 + 1/3 - 1/4 + 1/5 -1/6 + ...
求出该多项式的前n项的和。一个正整数m(m<100),为测试实例的个数,第二行包含m个正整数,对于每一个整数(设为n,n<1000),求该多项式的前n项的和。输出一行,保留两位有效数字。
2.解题思路:1》将多项式用循环结构表示出来。2》创建一个包含m个元素的数组。3》根据数组元素n将前n项和输出。
3. #include<stdio.h>
#include<math.h>
int main()
{
int m,a[100];
float x=0;
scanf("%d",&m);
for(int i=0;i<m;i++)
{
scanf("%d",&a[i]);//创立关于n的数组//
}
for(int j=0;j<m;j++)
{
for(int i=0;i<a[j];i++)
{
x=(1/float(i+1))*pow(-1,i+2)+x;//利用循环变量表示多项式//
}
printf("%.2f\n",x);//结果保留两位有效数字//
x=0;
}
return 0;
}
三.第一套.Problem G
1. 简要题意:选手得分规则为去掉一个最高分和一个最低分,然后计算平均得分,输出某选手的得分每行的第一个数是n(2<n<=100),表示评委的人数,然后是n个评委的打分。
2. 解题思路:1》将选手成绩存入数组中。2.》数组排序,利用循环结构输出平均值。
3. #include<iostream>
#include<algorithm>//使用sort函数对选手成绩进行排序//
using namespace std;
int main()
{
int n,a[110],x=0;
float b;
while(scanf("%d",&n)!=EOF)//输入多组数据//
{
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);//将一组数据中选手成绩输入数组a中//
}
sort(a,a+n);
for(int i=1;i<n-1;i++)//利用循环结构只保留中间成绩//
{
x=x+a[i];//计算选手成绩总和//
}
b=float(x)/(n-2);//计算平均值//
printf("%.2f\n",b);//保留两位数字输出平均成绩//
x=0;//循环变量初始化//
}
return 0;
}
四.第一套.Problem J
1. 简要题意:插入一个数使原数列仍保持有序(插入排序).
2. 解题思路:1》将原数列存入数组中,新插入的数就当做数组最后一个数。2》利用sort函数将新数组排序,并输出数组元素。
3. #include<iostream>
#include<algorithm>//调用sort函数
using namespace std;
int main()
{
int n,m,a[110];
while(cin>>n>>m)
{
if(n==0&&m==0) break;//标志输入结束
for(int i=0;i<n;i++)
{
cin>>a[i];
}
a[n]=m;//将新插入的数放入数组中
sort(a,a+n+1);//对新数组进行排序
for(int i=0;i<n;i++)
{
cout<<a[i]<<" ";//输出前n-1个数(包括空格0)
}
cout<<a[n]<<""<<endl;//输出最后一个元素
}
return 0;
}
五.第一套Problem D
1. 简要题意:对于表达式n^2+n+41,当n在(x,y)范围内取整数值时(包括x,y)(-39<=x<y<=50),判定表达式的值是否都为素数。
2. 解题思路:输入多组数据,设置标记变量,判断表达式值是否都为素数。
3. #include <stdio.h>
int main()
{
int n,x,y,fx,p=0;
while(scanf("%d %d",&x,&y)!=EOF)//输入多组数据
{
if(x==0&&y==0) break;//结束标志
for(n=x;n<=y;n++)
{
fx=n*n+n+41;//求区间内所有表达式的值
for(int i=2;i<=fx/2;i++)
{
if(fx%i==0) p++;//判断表达式值是否为素数
}
}
if(p==0) printf("OK\n");
else printf("Sorry\n");
p=0;//循环变量初始化
}
return 0;
}
六.第二套problemA
1. 简要题意:第一天悟空吃掉桃子总数一半多一个,以后每天吃掉前一天剩下的一半多一个,第n天只剩下一个桃子,求n。
2. 解题思路:利用循环结构和数学思想列出方程,算出n。
3. #include<stdio.h>
int main()
{
int n,m,i;
while(scanf("%d",&n)!=EOF)//输入多组数据
{
m=1;//循环变量定义
for(i=0;i<n-1;i++)
{
m=(m+1)*2;//算得第几天
}
printf("%d\n",m);
}
return 0;
}
七.第一套 Problem K
1. 简要题意:输入老师工资,人民币一共有100元、50元、10元、5元、2元和1元六种,判断要准备多少张纸币。
2. 解题思路:将老师工资存入数组,并用条件语句和循环语句判断老师所获纸币张数。
#include<stdio.h>
int main()
{
int a[110],n,m,l,k,sum=0;
while(scanf("%d",&n)!=EOF)//老师工资多组输入
{
if(n==0) break;//输入结束标志
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);//将老师工资存入数组
}
for(int i=0;i<n;i++)
{
sum+=a[i]/100;//判断100元纸币张数
if(sum!=0)//如果工资大于100,同下
a[i]%=100;
sum+=a[i]/50;//判断50元纸币张数
if(a[i]/50!=0)
a[i]%=50;
sum+=a[i]/10;
if(a[i]/10!=0)
a[i]%=10;
sum+=a[i]/5;
if(a[i]/5!=0)
a[i]%=5;
sum+=a[i]/2;
if(a[i]/2!=0)
a[i]%=2;
sum+=a[i];
}
printf("%d\n",sum);
sum=0;
}
}
八.第一套 Problem M
1. 简要题意:输入一个十进制数N,将它转换成R进制数输出。
2. 解题思路:参照十进制转化为二进制的方法,对输入数字进行取余和除法运算。
3. #include<stdio.h>
#include<string.h>
int main()
{
int n,r,i;
while(scanf("%d %d",&n,&r)!=EOF)
{
if(n<0)//处理负数进制转化
{
printf("-");n=-n;
}
if(n==0)//处理数字为零的情况
{
printf("0\n");
continue;
}
int c=0,a[100];
while(n)
{
a[c]=(n%r);
c++;
n/=r;
}
for(i=c-1;i>=0;i--)
{
if(a[i]>=10)
{
printf("%c",'A'+a[i]-10);//将十六进制表示字母用字符输出
}
else printf("%d",a[i]);
}
printf("\n");
}
}
九.第一套 Problem O
1. 简要题意:求两个集合的并集,规则:”A-B”表示如果A中的数字,B中有与之重合的,则结果就为A中剩下的数。
2. 解题思路:将集合A和集合B分别存入数组中,找出两数组中相同的数。写入标记数,使A与B相同的数记0,将A中不与B相同的数按顺序输出。
3.#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int n,m,a[100],b[100],p;
while(scanf("%d %d",&n,&m)!=EOF)//输入多组数据
{
if(n==0&&m==0) return 0;//输入数据结束标志
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);//将A中元素存入数组
}
for(int i=0;i<m;i++)
{
scanf("%d",&b[i]);//将B中元素存入数组
}
p=0;//定义标记变量
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(a[i]==b[j]) {a[i]=0; p++;}//查找两数组中有多少相同的数
if(p>=n) printf("NULL");//如果A中元素B中全部有
sort(a,a+n);//将A排好顺序
for(int i=0;i<n;i++)
{
if(a[i]==0) printf("");
if(a[i]!=0){printf("%d ",a[i]);}//按顺序输出
}
printf("\n");
}
return 0;
}
十.Problem R
1.简要题意:有一楼梯共M级,开始时在第一级,若每次只能跨上一级或二级,要走上第M级,共有多少种走法。
2.解题思路:建立数组,由于一开始处于第一级,找出数学规律,利用循环结构求解。
3.
#include<stdio.h>
int main()
{
int N,m,a[41];
scanf("%d",&N);
a[1]=0;//在第一级台阶时
a[2]=1;//在第二级台阶时
a[3]=2;//在第三季台阶时种数
for(int i=4;i<41;i++)
{
a[i]=a[i-1]+a[i-2];
}
while(N--)//输入N个数据
{
scanf("%d",&m);
printf("%d\n",a[m]);
}
return 0;
}.
十一.第一套.Problem U
1. 简要题意:一个11位长的手机号码,所有的短号都是是 6+手机号的后5位,要求输出短号。
2. 解题思路:将十一位数字作为字符存入数组中,并根据要求输出后五位并加入一个5。
3.
#include<iostream>
using namespace std;
int main()
{
int n;
char a[12];
cin>>n;
while(n--)//输入11字符
{
for(int i=1;i<=11;i++)
cin>>a[i]; ;//将数字作为字符存入数组中
cout<<6;
for(int i=7;i<=11;i++)
cout<<a[i];//输出校园短号
cout<<endl;
}
return 0;
}
十二.第二套.Problem E
1. 简要题意:把一个偶数拆成两个不同素数的和,有几种拆法呢?
2. 解题思路:找出1到该偶数之中所有的素数存入一数组中,利用循环结构将不同素数组数算出。
3.
#include <stdio.h>
#include <math.h>
int main()
{
int n,a[10000],i,T,l,j,count;
while(scanf("%d",&n)!=EOF)//多组数组输入
{
if(n==0) break;//输入数据结束标志
count=l=0;//设置计数变量
for(i=2;i<=n-2;i++)
{
T=1;//设置标记变量
for(j=2;j<=sqrt(i);j++)
{
if(i%j==0)//不是素数
{
T=0;
break;
}
}
if(T==1)//是素数
{
a[l]=i; l++;
}
}
for(i=0;i<l;i++)
{
for(j=i+1;j<l;j++)
{
if(a[i]+a[j]==n)//找素数之和为该偶数
count++;
}
}
printf("%d\n",count);
}
return 0;
}
十三.第二套problem C
1. 简要题意:在一个平面内有两个点,求两个点分别和原点的连线的夹角的大小。注:夹角的范围[0,180],两个点不会在圆心出现。
2. 解题思路:利用数学函数和余弦定理将角度算出
3.
#include <stdio.h>
#include <math.h>
const double pi = 3.1415926;//定义宏常量
int main()
{
int n;
scanf("%d",&n);
while(n--)//输入n组数据
{
double x1,x2,y1,y2,t,a,b,c,max;
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
a = sqrt(x1*x1+y1*y1);
b = sqrt(x2*x2+y2*y2);
c = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));//计算两点之间的距离
t = (a*a+b*b-c*c)/(2.0*b*a);//利用余弦定理
t = acos(t)*180/pi;//将角度转化成角度
while(t>180)//处理大于180度角情况
t-=180;
printf("%.2lf\n",t);//结果保留两位数字输出
}
return 0;
}
十四:第一套.Problem P
1. 简要题意;求A^B的最后三位数表示的整数。说明:A^B的含义是“A的B次方”。
2. 解题思路:利用循环结构找出符合数字即可。
3.
#include <iostream>
using namespace std;
int main()
{
int a,b,x,i;
while(cin>>a>>b,a!=0||b!=0)//输入多组数据
{
x=1;//设置循环变量
for(i=1;i<=b;i++)
x=(a*x)%1000;
cout<<x<<endl;
}
return 0;
}
十五.第二套. Problem G
1. 简要题意:寻找二个整数,它们加起来等于某个整数,乘起来又等于另一个整数。
2. 解题思路:利用循环结构找出符合条件。
3.
#include <cstdio>
#include <cmath>
#include <iostream>
using namespace std;
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)//输入多组数据
{
if(n==0&&m==0) break;//结束输入标志
if((int)sqrt(n*n-4*m)==sqrt(n*n-4*m))//确认该数是否符合条件。
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
return 0;
}
总结:
通过多道题的练习,每个题几乎必备的就是“多组输入”,“循环结构”,“数组”和“条件结构”。有些题需要应用数学规律进行计算,并且需要在程序中调用一些头文件来使用数学函数。
在做题中需要注意的(仅是自己的看法)
1. 数组的应用十加巧妙,通过数组将结果输出,可另最后一个数字不和空格一起输出就不会导致输出错误。
2. 定量数据的输入通过“while(n--)”来实现使结构清晰。其次输入多组数据时的循环变量初始化也是必不可少的,不初始化,即使第一组测试数据正确,也不能保证输出的多组数据都是正确的。
3. 标志变量的建立有时对程序建立有着至关重要的作用,标志变量不仅能起到技术的作用,而且还能使编写的程序更加简便。
4. 将紧密相连的数字串分开放入数组中时,可利用字符数组,使每个数字变为字符,根据题目要求选取部分输出数组元素,有些问题就变的迎刃而解了。
5. 作为循环结构小细节中的”break”在结束输入数据中起着至关重要的作用。
6. 进制转化问题中应学会又二进制推广至多进制,利用循环结构进行进制数之间的转化。
最后,我认为c语言带给我们的不仅是问题的解决,而且是看待问题的观点。