《c++程序设计》课程设计报告
一、题目1(课设1,ProblemH)
1、题目简介
有一头头母牛,它每年年初生一头小母牛。每头小母牛从第四个年头开始,每年年初也生一头小母牛。在第n年的时候,共有多少头母牛?
2、思路形成
首先,定义一组数组,储存着N组数据。输入n,代表第几年,0<n<4时,只有最初的一头母牛能生小牛,到第四年时,母牛在第一年生的小牛也可以生牛了。出生的小母牛每活三年就能再生新的小母牛了。2f(1)=1 f(2)=2 f(3)=3 f(4)=4 f(5)=6当第n年的时候,所有的牛应该有第n-1年的牛+第n-3年的年都能生,推出f(n)=f(n-1)+f(n-3)
3、源代码
#include<stdio.h>
int main()
{
int N,j;
int a[1000];
scanf("%d",&N);
int n,i;
for(j=0;j<N;j++)
{
scanf("%d",&n);
a[j]=n;
}
for(j=0;j<N;j++)
{
n=a[j];
int f1=0,f2=0,f3=0,f4=1,f;
if(n>0)
{
for(i=1;i<n;i++)
{
if(n==1)
f=1;
else
{
f4=f3+f4;
f3=f2;
f2=f1;
f1=f4;
f=f1+f2+f3+f4;
}
}
printf("%d\n",f);
}
else
printf("\n");
}
return 0;
}
4、细节处理
n=0时表示输入数据的结束,不做处理;注意0<n<55。
二、题目2(课设1,ProblemI)
1、题目简介
输入n(n<=100)个整数,按照绝对值从大到小排序后输出。
2、思路形成
首先将这些整数n存储在一个数组中,输入n后再输入这个数组,因为整数中可能存在负数,不好比较,所以将每个数平方后再进行比较。使用冒泡排序法,前面的数依次与后一个数相比,如果比后面的数小,则和后面的一个数交换位置,最后输出这个数组。
3、源代码
include <iostream>
using namespace std;
int main()
{
int a[100],i,j,t,n;
while(cin>>n&&n!=0)
{
for(i=0; i<n; i++)
cin>>a[i];
for(j=0; j<n; j++)
for(i=0; i<n-1-j; i++)
if(a[i]*a[i]<a[i+1]*a[i+1])
{
t=a[i];
a[i]=a[i+1];
a[i+1]=t;
}
for(i=0; i<n-1; i++)
cout<<a[i]<<" ";
cout<<a[n-1]<<endl;
}
return 0;
}
4、细节处理
通过比较整数的平方来判断其绝对值的大小;最后不能有空格;n=0时表示输入数据的结束,不做处理。
三、题目3(课设1,ProblemG)
1、题目简介
评委给参赛选手打分,选手得分规则为去掉一个最高分和一个最低分,然后计算平均得分,请编程输出某选手的得分。
2、解题思路形成
开始令最大值和最小值都等于a,输入数据逐个与最大值比较,如果该数比最大值大,则将其赋值给最大值,最小值原理相同,然后对这组数据求和,最后输出时和减去最大值和最小值,求平均值。
3、源代码
#include<stdio.h>
int main()
{
int n,i,a,max,min,sum;
while(scanf("%d",&n)==1)
{
scanf("%d",&a);
sum=max=min=a;
for(i=1;i<n;i++)
{
scanf("%d",&a);
if(a>max) max=a;
if(a<min) min=a;
sum+=a;
}
printf("%.2f\n",(sum-max-min)*1.0/(n-2));
}
return 0;
}
4、细节处理
保留两位小数,开始max,min和sum赋值相同。
四、题目4(课设1,ProblemE)
1、题目简介
求多项式1 - 1/2 + 1/3 - 1/4 + 1/5 - 1/6 + ...的前n项的和
2、解题思路形成
为避免混乱,循环分母,最后求和的时候用pow函数和,除了第一项,其他的都带负号
3、源代码
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
int main()
{
int m,n,i;
float s;
while(cin>>m)
{
while(m--)
{
s=0;
cin>>n;
for(i=1; i<=n; i++)
s += ( 1 / ( ( pow( (-1), (i+1) ) ) * i ) );
cout <<fixed<< setprecision(2) << s;
cout << endl;
}
}
return 0;
}
4、细节处理
注意最后保留两位小数,用pow函数头文件要用cmath。
五、题目5(课设1,ProblemB)
1、题目简介
“水仙花数”是指一个三位数,它的各位数字的立方和等于其本身,比如:153=1^3+5^3+3^3。
现在要求输出所有在m和n范围内的水仙花数。
2、解题思路形成
先输入一个区间,循环区间中的数字,判断其是否为水仙花数,是的话,count+1。如果只有一个水仙花数,直接输出i,没有的话,输出"no"。
3、源代码
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
int l,r;
while(cin >> l >> r)
{
int count = 0;
for(int i=l;i<=r;i++)
{
int sum = pow(i%10,3) + pow((i/10)%10,3) + pow(i/100,3);
if(sum == i)
{
count++;
if(count == 1)
cout << i;
else
cout << " " << i;
}
}
if(count == 0)
cout << "no";
cout << endl;
}
return 0;
}
4、细节处理
注意题目输出要求,最后一个数后不可有空格。
六、题目6(课设1,ProblemC)
1、题目简介
给你n个整数,求他们中所有奇数的乘积。
2、解题思路形成
输入数组,用求余来判断其是否为奇数,是的话,存入数组,依次相乘,最后输出。
3、源代码
#include<cstdio>
#include<iostream>
using namespace std;
int a[1000001];
int main()
{
int n,i,sum=1;
while(cin>>n)
{
for(i=0;i<n;i++)
cin>>a[i];
sum=1;
for(i=0;i<n;i++)
{
if(a[i]%2!=0) sum*=a[i];
}
cout<<sum<<endl;
}
return 0;
}
4、细节处理
确保数组的容量足够大
七、题目7(课设1,ProblemJ)
1、题目简介
有n(n<=100)个整数,已经按照从小到大顺序排列好,现在另外给一个整数x,请将该数插入到序列中,并使新的序列仍然有序。
2、思路形成
首先,将这组数放在数组a中,输入数组,用冒泡排序法,将要插入的数x输入,依次与数组中的数比较,如果这个数比下一个数小,则跳出循环。否则,交换顺序。这就将数x插入在数组a中,使之成为了一个新的数组,然后将这个新序列的数组输出。
3、源代码
#include <stdio.h>
int main()
{
int n, x, a[100], i, j;
while(scanf("%d%d",&n,&x)&&(n||x))
{
for(i=0;i<n;i++)
scanf("%d",&a[i]);
for(i=0;i<n;i++)
{
if(x<a[i])
break;
}
for(j=0;j<i;j++)
printf("%d ",a[j]);
printf("%d",x);
for(j=i;j<n;j++)
printf(" %d",a[j]);
printf("\n");
}
return 0;
}
4、细节处理
当插入数不需要与后一个数交换位置时,跳出循环。
八、题目8(课设1,ProblemL)
1、题目简介
“回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。判断读入的字符串是否是“回文”。
2、解题思路形成
判断一个字符串从前往后读和从后往前读都是相同的字符顺序,用函数解决比较简单。首先定义一个字符串,将其输入,另外构造一个字符串,使其为当前字符串的倒序,然后比较两字符串是否相等。
3、源代码
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main ()
{
int n;
while(cin>>n)
for(int i=0;i<n;i++)
{
string s;
cin>>s;
string s1=s;
reverse(s1.begin(),s1.end());
if(s1==s) cout<<"yes"<<endl;
else cout<<"no"<<endl;
}
return 0;
}
4、细节处理
用字符串时头文件要用string;字符取反时用函数reverse,固定格式reverse(s1.begin(),s1.end())表示对字符串s取反。
九、题目9(课设2,ProblemG)
1、题目简介
有二个整数,它们加起来等于某个整数,乘起来又等于另一个整数,判断这种整数是否存在。
2、解题思路分析
首先输入两个整数的和与积,用△公式,△=(-b+-√b²-4ac)/2a。
3、源代码
# include <iostream>
# include <cstdio>
# include <cstring>
# include <cmath>
using namespace std;
int main()
{
int n,m;
int t;
while(cin>>n>>m,n!=0||m!=0)
{
int num = n*n - 4*m;
t = sqrt(num);
if(t*t==num)
{
cout<<"Yes"<<endl;
}
else
{
cout<<"No"<<endl;
}
}
return 0;
}
4、细节处理
m和n同时为0时不做处理;要判断是否是整数。
十、题目10(课设1,ProblemO)
1、题目简介
求集合A和B的减法运算
2、解题思路形成
集合的减法,A-B即是求集合A中有但是集合B中没有的元素,通过二位数组来a[2][100]存储A集合中的元素.a[0][a]储存A中元素.a[1][a]判断是否有重复的。
3、源代码
#include<stdio.h>
paopao(int A[],int number)
{
int i,j,t;
for(i=0;i<number-1;i++)
for(j=0;j<number-i-1;j++)
{
if(A[j]>A[j+1])
{
t=A[j];
A[j]=A[j+1];
A[j+1]=t;
}
}
}
int main()
{
int m,n;
int a,b,c;
int judge;
while(1)
{
int A[2][100]={0},B[100];
judge=0;
scanf("%d%d",&n,&m);
if(n==0&&m==0) break;
for(a=0;a<n;a++)
{
scanf("%d",&A[0][a]);
A[1][a]=1;
}
paopao(A[0],n);
for(a=0;a<m;a++)
scanf("%d",&B[a]);
for(a=0;a<n;a++)
for(b=0;b<m;b++)
{
if(A[0][a]==B[b]) A[1][a]=0;
}
for(a=0;a<n;a++)
if(A[1][a]==1)
{
printf("%d ",A[0][a]);
judge=1;
}
if(judge==0) printf("NULL");
printf("\n");
}
return 0;
}
4、细节处理
结果需要从小到大输出,在得出结果之后需要进行一次排序,这里可以用sort函数来进行排序;m和n同时为0时不做处理。
十一、题目11(课设1,ProblemR)
1、题目简介
有一楼梯共M级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第M级,共有多少种走法?
2、解题思路形成
定义台阶数数组,,将前四十个数储存起来,采用递归法,总结出a[i]=a[i-1]+a[i-2]。
3、源代码
#include<stdio.h>
int main()
{
int N=0,M=0,i=0,sum=0,a[41]={0};
scanf("%d",&N);
a[1]=1;
a[2]=1;
for(i=3;i<=40;i++)
a[i]=a[i-1]+a[i-2];
while(N--)
{
scanf("%d",&M);
printf("%d\n",a[M]);
}
return 1;
}
4、细节处理
每次走一阶或两阶,开始给a[1]和a[2]赋值1,return 1。
十二、题目12(课设1,ProblemU)
1、题目简介
假设所有的短号都是是 6+手机号的后5位,给出一个11位长的手机号码,找出对应的短号。
2、解题思路形成
用字符串。首先输入这个字符串(11位号码),因为短号前都有6,所以先输出"6",循环时从第七位开始找号码,把号码第七位到第十一位输出。
3、源代码
#include<stdio.h>
#include<string.h>
int main()
{
int t,i;
char s[15];
scanf("%d",&t);
while(t--)
{
scanf("%s",s);
printf("6");
for(i=6;i<strlen(s);i++)
printf("%c",s[i]);
puts("");
}
return 0;
}
4、细节处理
用到了函数strlen代表字符串的长度。
十三、题目13(课设2,ProblemA)
1、题目简介
第一天吃掉桃子总数一半多一个,以后每天吃掉前一天剩下的一半多一个,到第n天准备吃的时候只剩下一个桃子。求第一天开始吃的时候桃子的数量。
2、解题思路形成
找规律求解,因为每天吃掉前一天剩的一半多一个,桃子的总数就可以表示为前一天的数加一再乘二,求和后输出。
3、源代码
#include<stdio.h>
int main()
{
int i,n,sum;
while(scanf("%d",&n)!=EOF)
{
sum=1;
if(n>1&&n<30)
for(i=1;i<n;i++)
{
sum=(sum+1)*2;
}
printf("%d\n",sum);
}
return 0;
}
4、细节处理
桃子数小于30且不为负,总数是指截止到某天的总数,不是当天的数量。
十四、题目14(课设2,ProblemC)
1、题目简介
在一个平面内有两个点,求两个点分别和原点的连线的夹角的大小。
2、解题思路形成
已知两点坐标要求其到原点连线的夹角,可以用向量去做,用向量的积除以向量模的乘积,再求其反函数,然后转换为角度就可以知道其角度。
3、源代码
#include<iostream>
#include<cmath>
#include<cstdio>
#include<iomanip>
using namespace std;
#define PI 3.14159
int main()
{
double x1, x2, y1, y2;
double n,m;
int t;
cin>>t;
while (t--)
{
cin>>x1>>y1>>x2>>y2;
n = sqrt(x1*x1 + y1*y1)*sqrt(x2*x2 + y2*y2);
m= x1*x2 + y1*y2;
cout<<acos(n / m) / PI*180.0<<endl;
}
return 0;
}
4、细节处理
最后弧度要转换为角度,用函数sqrt求模。
十五、题目15(课设1,ProblemN)
1、题目简介
求两个时间A和B的和(包括时、分、秒)
2、思路形成
输入两组时、分、秒,先求秒数的和,遇到六十进一,再求分数的和,将两数的分数相加后再加上秒数进的数,遇到六十进一,最后求时数,时数相加后再加上分数进的一。最后输出时数、分数和秒数。
3、源代码
#include<stdio.h>
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
int ah,am,as,bh,bm,bs;
scanf("%d%d%d%d%d%d",&ah,&am,&as,&bh,&bm,&bs);
int a,b,c;
c=(as+bs)%60;
b=((as+bs)/60+am+bm)%60;
a=((as+bs)/60+am+bm)/60+ah+bh;
printf("%d %d %d\n",a,b,c);
}
return 0;
}
4、细节处理
时间是六十进制,每个数都要小于六十,不能直接想加求和,求的时候从秒数到分数,再到时数比较容易。
十六、学习总结
通过三天的课程设计,让我感触颇多。由于元旦假期的原因,原来应该持续时间为一周的课程设计缩成了三天,说实话,32个比较有难度的题,让我三天做完是不可能的,时间太紧了。这次课程设计的题目又和以前的题目不太一样,每个都要求是用多组数据输入输出,这就用到了while(cin<<n);当n=0时不作处理,if(n==0) return 0;最后一个数据输出时,后面不能有空格。即使这三天我们是自己封闭式的做题,但真的学到了很多。虽然最后我并没有把所有的题目做完,但我真的尽力了,和以前相比真的有了很大的进步。大一上学期的结束意味着《课程设计A》这门课程的结束,但并不意味着对C++的学习止步于此。我真的还有很多的不足之处,以后会慢慢解决的!