c++程序设计

《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语言!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值