《c++程序设计》课程设计报告
班级: 数学四班 学号:2018212821
报告人姓名: 苏瑞琳
实验地点:
东校区413
完成起止日期:2018.12.28至2019.01.04
一。
现在要求输出所有在m和n范围内的水仙花数。
思路:首先输入一个范围,第一步,先找到水仙花数,每找到一个累加一
AC
#include
#include
#include
using namespace std;
int main()
{
int n,m,a,b,c,d,i;
while(cin>>m>>n)
{
d=0;
//计算水仙花数的个数,开始赋值为0且一定赋值在while内
for(i=m;i<=n;i++)
{
a=i/100; //百位
b=i/10%10; //十位
c=i%10; //个位
if(i==aaa+bbb+ccc)
{
d++; //由于出现了水仙花数,d加一
if(d==1) //此时为第一个水仙花数,直接输出即可
cout<<i;
else //d为2的情况,表示前边已经有一个水仙花数了,故需要先求出一个空格
cout<<" "<<i;
}
}
if(d==0) //说明在范围内并未找到水仙花数
printf(“no\n”); //输出no即可
if(d!=0)
printf("\n"); //此时表示跳出了水仙花数寻找的循环,即,所有的水仙花数在范围内已经找完了, 要寻找下一组数据了故换行
}
return 0;
}
二。
给你n个整数,求他们中所有奇数的乘积。
思路:首先将数据输入进去,然后在判断是为奇数么,如果是,就累乘,
AC
#include
#include
#include
using namespace std;
int main()
{
int m,n,i,p;
while(cin>>m) //直接输入每行数据的个数,再紧跟其后输入数据
{
n=1;
//开始数据,因为要做乘法,底为1
for(i=1;i<=m;i++)
{
cin>>p; //此时就表示随着循环依次输入这三个数,先判断,
if(p%2==1) //判断是否为奇数
n*=p;//进行累乘
}
cout<<n<<endl;//一个for循环结束,也就是一行数据循环完,要换下一行的数据,继续循环
}
return 0;
}
三。
对于表达式n^2+n+41,当n在(x,y)范围内取整数值时(包括x,y)(-39<=x<y<=50),判定该表达式的值是否都为素数
思路:首先,先讲这个范围内的数输入进去,找到其对应函数值的上限,再再次范围内寻找素数,如果全是为素数,那么就是YES
AC
#include
#include
#include
#include
using
namespace std;
int
a[3000],b[90];
int main()
{
int x,y,l,s;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
while(cin>>x>>y)
{
l=0;
if(x0&&y0)
return 0;//题目已经说明了,当x,y均为0时,表示输入结束,不做处理!
for(int i=x,j=1;i<=y&&j<=y-x+1;i++,j++)
{
b[j]=i;//x y范围内的所有数
}
for(int i=41;i<=2591;i++)//41,2591分别是表达式给出的范围中的对应函数值最大值与最小值
{
s=0;
for(int j=2;j<sqrt(i);j++) //折半查找,节省次数
{
if(i%j==0)//素数应该除了1和它本身外没有其他因子,能除以2及以上的,也就是能除以1和它本身之外的数了,显然非素
break;
else
s++;//此时表示正在验的值是素,有s暂时存素数的个数,一会验证s是否等于x-y+1
}
if(s+2>sqrt(i))
a[i]=i;只有这样才有可能为素数,将此时筛出的i在做处理,经过这样,可以明显减少运算次数
}
for(int i=41;i<=2591;i++)
for(int j=1;j<=y-x+1;j++)
{
if(a[i]==b[j]*b[j]+b[j]+41)
{
l++;
}
}
if(l==y-x+1)//表示此范围内的所有数都是素数!
cout<<“OK”<<endl;
else
cout<<“Sorry”<<endl;
}
return 0;
}
四题。多项式求和
1 - 1/2 + 1/3 - 1/4 + 1/5 - 1/6 + …
现在请你求出该多项式的前n项的和。
思路:由于是正负交替出现的,那么此时最重要的就是让其正负出现
AC
#include
#include
#include
using namespace std;
int main()
{
int m,n,i,j,b;
double a;
while(cin>>m)
{
for (i=1;i<=m;i++)
{
cin>>n;
a=0;
for (j=1;j<=n;j++)
{
b=1;
if (j%2==0)//分母为偶数时,为负
{
b=(-1);
}
a=a+b*(1.00/j);
}
printf("%.2lf\n",a);
}
}
return
0;
}
五题。
有一个长度为n(n<=100)的数列,该数列定义为从2开始的递增有序偶数,现在要求你按照顺序每m个数求出一个平均值,如果最后不足m个,则以实际数量求平均值。编程输出该平均值序列。
思路:我认为最重要的是如何对齐分组,因为可能存在剩余的情况,那么先分出满m的组,剩下的单独进行求平均值
AC
#include<stdio.h>
void main() //void比int适用范围更广
{
int n,m,i,j,sum=0,k;
while(~scanf("%d%d",&n,&m))//读取操作,等价与(scanf("%d%d",&n,&m)!=EOF)
{ k=0;
for(i=1;i<=n/m;i++)//先将n个数分成i个组,每组m个剩下的没有被分组得会在下面的if语句中进行剩余求平均数
{ sum=0;
if(i>1) printf(" ");//规定输出格式,每个数之间用空格隔开,当i=1时,表示第一个数,不用加空格,从第一个往后才开始用加空格
for(j=1;j<=m;j++)//将每个组里的数相加并求平均数
{
k=k+2;
sum+=k;
}
printf("%d",sum/m);
}
if(n%m)
{
//分成i个组后剩余的数求平均数
sum=0;
for(j=1;j<=n-n/m*m;j++)//n/m表示分成的含有m个元素的组数,乘以m表示成功分组得所有元素,与n作差,剩余的是未成功分组得
{
k=k+2; //接着从上面的k开始递增
sum+=k;
}
printf(" %d",sum/(j-1));//因为有j++多加了一个1
}
printf("\n");
}
}
六题。评委会给参赛选手打分。选手得分规则为去掉一个最高分和一个最低分,然后计算平均得分
思路:
AC
#include
#include
#include
int main()
{
int sum=0,i,n,score,min,max;
double ave;
while(scanf("%d",&n)!=EOF)
{
min=100;
max=0;
sum=0;//开始没有在这里加该句,一直显示wrong answer
for(i=1;i<=n;i++)
{
scanf("%d",&score);
sum+=score
if(score>max)
{
max=score;
}
if(score<min)
{
min=score;
}
}
ave=(sum-max-min)*1.00/(n-2);
printf("%.2lf\n",ave);
}
return 0;
}
七题。
一头母牛,它每年年初生一头小母牛。每头小母牛从第四个年头开始,每年年初也生一头小母牛。请编程实现在第n年的时候,共有多少头母牛?
思路:这是一个递归问题,每一个年份都与其上一个年份有关,用abcd表示四个年份,依次轮流赋值
AC
#include
using namespace std;
int main()
{
int n;
while(cin>>n)
// 后面一定不能加符号
{
if(n==0)break;跳出的哪个循环?
int a,b,c,d; //分别代表一岁二岁三岁四岁及其以上的母牛的数目。
if(n<=4)cout<<n<<endl; //若n<=4,很容易得出总数为n
else{
n=n-4;
a=b=c=d=1;
for(int
i=0;i<n;i++)
{
d=c+d;//当年大母牛数目d为前一年c和d的总和
c=b;//b母牛长了一岁到了c
b=a;//同上
a=d;//长成的母牛和原本的母牛共生出新的小母牛a个
}
cout<<a+b+c+d<<endl;
}
}
}
八题。
入n(n<=100)个整数,按照绝对值从大到小排序后输出。题目保证对于每一个测试实例,所有的数的绝对值都不相等。
AC
#include
#include
using namespace std;
int main()
{
int n,i,j,a[100],max;
while(cin>>n)
//多组数据的输入
{
if(n==0) break; //如果输入0程序结束(可以把此句去掉把while(cin>>n)修改为while((cin>>n)&&n!=0)
for(i=0;i<n;i++) //输入数组a
cin>>a[i];
for(i=0;i<n-1;i++) //对数按绝对值从大到小选择法排序
{
max=i;
for(j=i+1;j<n;j++)
{
if(abs(a[max])<abs(a[j]))
max=j;
}
if(a[max]!=a[i])
swap(a[max],a[i]);
}
for(i=0;i<n;i++)
{
cout<<a[i];
if(i<n-1) //注意最后没空格在此做个判断
cout<<’ ';
}
cout<<endl;
}
return 0;
}
九题
在已存在的有序数列中再查入一个元素,使其仍然有序
有n(n<=100)个整数,已经按照从小到大顺序排列好,现在另外给一个整数x,请将该数插入到序列中,并使新的序列仍然有序
思路:在我看来,重点在于自动升序排列函数的使用
.默认的sort函数是按升序排。对应于sort(a,a+n);
//两个参数分别为待排序数组的首地址和尾地址
AC
#include
#include
using namespace std;
int main()
{
int n,m,a[101];
while(cin>>n>>m)
{
if(n0&&m0) 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]<<" ";
}
cout<<a[n]<<""<<endl;
}
return 0;
}
十三。
进制转换
思路:我认为,这和十进制的数分别提取个位,十位,百位方法一样,重点就在于我先存下这些进制使用的字符
#include
using namespace std;
int main(){
char
str[17]=“0123456789ABCDEF”;//用一个字符型数组存好"0123456789ABCDEF"
int n,m,tmp,i,j;
int r[100];
while(scanf("%d%d",&n,&m)!=EOF)
{
i=0;tmp=1;
if(n<0)
{
//如果n<0,则输出负号,然后把n变成整数
printf("-");
n=-n;
}
while(tmp!=0)
{ //用除R取余法模拟,并把余数放到数组里面
r[i]=n%m;
n=n/m;
tmp=n;
i++;
}
for(j=i-1;j>=0;j–)
printf("%c",str[r[j]]);//输出结果。
printf("\n");
}
return 0;
}
十题
两组数据中的分秒时求和计算
思路:由于秒与分,存在60进制问题不能无限次的累加,要利用对秒60取余得秒,对秒60取整得分,而小时则是小事累加后加上,分钟对60取整
#include <stdio.h>
int main()
{
int N,AH,AM,AS,BH,BM,BS,h,m,s,k;
scanf ("%d",&N);//输入要处理的行数
while (N–)//倒计数直至1
{
scanf("%d%d%d%d%d%d",&AH,&AM,&AS,&BH,&BM,&BS);
s=(AS+BS)%60;//对60取余得秒
k=(AS+BS)/60;//由秒积成的分钟
m=(AM+BM+k)%60;//对60取余得分钟
k=(AM+BM+k)/60;//有分钟积成的小时
h=AH+BH+k;//对小时直接进行累加即可,因为没有60进制的限制
printf ("%d %d %d\n",h,m,s);
}
return 0;
}
十一题。
A的B次方的后三位
思路;a的b次方,要通过b个a相乘得到,行程循环
#include
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;//防止数据的溢出,并且也只让求后三位对1000求余剩下的就是百十个三位,在进行乘法,以同样的方式保留三位即可
cout<<x<<endl;
}
return 0;
}
注意:算一次就要取余一次。
要考虑溢出的情况
ab的时候,如果a和b比较大,结果只需要最后三位,每次只需要保留上一次结果的最后3位即可,而不需要保留an次方的整个结果,其中n = 1、2、……、b
十二题。爬台阶
每次走一级或两级,到第m级,一共有多少种方法
解题思路:递归实现.
重要的是理解这个逻辑
假设走到n阶时,有f(n)种走法,
当走到N-1阶台阶时,有f(n-1)种走法,再走一步走完。
当走到n-2阶台阶时,有f(n-2)种走法, 再走1+1或2,走完。其中走1+1和走到n-1阶时的f(n-1)重复。
所以f(n)=f(n-1))+f(n-2)
#include<stdio.h>
int f[41];
int main()
{
int n,m,i;
f[1]=0;
f[2]=1;
f[3]=2;
for(i=4;i<41;i++)
f[i]=f[i-1]+f[i-2];
scanf("%d",&n);
while(n–)
{
scanf("%d",&m);
printf("%d\n",f[m]);
}
return 0;
}
蜜蜂,与台阶相似(斐博纳西数列)
#include
using namespace std;
int main()
{
long long f1,f2,temp;
int n,m,k;
cin>>n;
while(n–)
{
cin>>m>>k;
f1=1;f2=1;
for(int i=1;i<k-m;i++)
{
temp=f1+f2;
f1=f2;
f2=temp;
}
cout<<f2<<endl;
}
return 0;
}
十三题。手机号码
#include
using namespace std;
int main()
{
int N;
cin>>N;
while(N–){
char a[11];
cin>>a;
cout<<‘6’;//要求输出6加后五位
for(int i=6;i<11;i++)//此处就是在寻找后五位
cout<<a[i];//此处的两个cout一定不能合在一起写,否则不是按要求输出的,如下两图所示
cout<<endl;
}
return 0;
}
十四。猴子吃桃
每天都要吃掉前一天剩下的一半并且再多吃一个,到了第n天还剩1个,求开始有几个
思路:具体推导如下图所示
#include<stdio.h>
int main() {
int i,n;
while(scanf("%d",&n)!=EOF)
{
int a=1;
for(i=1; i<n; i++)
a=(a+1)*2;
printf("%d\n",a);
}
return 0;
}
十五。寻找符合条件的两个整数x,y
使他们加起来等于一个数m乘起来等于另一个整数n
思路:如下图所示。
#include<math.h>
#include<stdio.h>
int main()
{
int n,m,x1,x2,y1,y2;
while(scanf("%d%d",&n,&m)&&!(n0&&m0))//输入的m n的顺序一定不能颠倒,否则会一直出错,输出no
{
int a;
a=nn-4m;
if(a<0) printf(“No\n”);
else
{
x1=(n+sqrt(a))/2;
y1=n-x1;
x2=(n-sqrt(a))/2;
y2=n-x2;
if(x1y1==m||x2y2==m)
printf(“Yes\n”);
else printf(“No\n”);
}
}
return 0;
}
十六。sky数
2992,这个数,它的十进制数表示,其四位数字之和为2+9+9+2=22,它的十六进制数BB0,其四位数字之和也为22,同时它的十二进制数表示1894,其四位数字之和也为22,
思路:输入一个数后,分别对其进行进制的转化,然后,再累加各进制每位上的数字
include <stdio.h>
int main()
{
int b[3],a[3]={10,16,12};//数组b贮存进制转换后的数,数组a贮存需要转换的进制
int i,sum,p,n;
while(scanf("%d",&n)!=EOF&&n!=0)//此处对n的限制,也可以写在下边,如下一个方法所示
{
for(i=0;i<3;i++)
{
p=n,sum=0;
while§
sum=sum+p%a[i],p=p/a[i];//一位位的往外提取
b[i]=sum;
}
if(b[1]==b[0]&&b[1]==b[2])//如果转换后的三个进制数相等
printf("%d is a Sky
Number.\n",n);//“ 。。。”中就已经限制了输出的形式,只不过用n来代替%d
else
printf("%d is not a Sky
Number.\n",n);
}
return 0;
}
总结:
做完这套题,意味着一个学期已经结束了,我学课程设计也就告一段落了。
今天,我该总结一下了,这一套题给我的感觉是,该组题测的很多都是多余数据,开始并不知道要测数据的组数,基本都是用while语句来解决的。
说实话,现在的我对字符型的处理,函数的调用都不熟悉,并且在处理数组时也存在很多欠缺,做完这套题最大的收获就是对while语句,for语句的使用更加熟悉了,相比之前,这一次集训巩固了我已经掌握的知识点,也认识到了自己的很多盲区,很多知识点并没有真正掌握!写这个总结,已经实在考试的前一天晚上,我知道很多问题已经决定了,一个晚上改变不了什么,但我相信,我认认真真对待了这套题,我就有收获,希望自己能够真正的学有所用,张老师说的一样,能用程序设计来解决实际问题!
最后,非常感谢老师对我的细心教导,每次问您题,或是电脑出故障了,您都很耐心的帮我解决,真的非常感谢您,我庆幸自己遇到了您这样的老师教我c语言!!