课程设计报告
数学二班
翟玉晓
2018212774
Problem 1
题意:
在某个范围内的水仙花数
思路:
用循环暴力求解
注意点:
输出格式的问题,当只有一个水仙花数的时候,这时要单独输出,不然会多输出空格。
代码:
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
int m,n,i,x,y,z,a;
while(cin>>m>>n)
{
int c=0;
for(i=m;i<=n;i++)
{
x=i%10;
y=i/10%10;
z=i/100;
a=x*x*x+y*y*y+z*z*z;
if(a==i)
{c++;
if(c==1)
cout<<a;
else
cout<<" "<<a;
}
}
if(c==0)
cout<<"no";
cout<<endl;
}
return 0;
}
题解:
x,y,z分别代表i的个位,十位,百位;
用一个变量c的值是否为0,来表示有没有找到水仙花数;
If条件里面,当c==1时,说明在(m,n)内只有一个水仙花数,所以这时候不需要输出空格;
Problem 2
题意:
长度为n的数列,该数列定义为从2开始的递增有序偶数,m个数求出一个平均值,如果最后不足m个,则以实际数量求平均值。
思路:
分两种情况:一是n整除m,这时正好分为n/m组,没有剩余;
二是n不整除m,分为n/m组+余数作为一组;
注意点:仍然是注意输出格式问题,同时不要忘记初始化变量,以及变量初始化的位置。
代码:
#include<iostream>
using namespace std;
int main()
{
int n,m,c,s;
while(cin>>n>>m)
{
c=0;
for(int i=1;i<=n/m;i++)
{
s=0;
if(i>1)
{
cout<<" ";
}
for(int j=1;j<=m;j++)
{
c=c+2;
s+=c;
}
cout<<s/m;
}
if(n%m!=0)
{
s=0;
for(int j=1;j<=n%m;j++)
{
c=c+2;
s+=c;
}
cout<<" "<<s/(n%m);
}
cout<<endl;
}
return 0;
}
题解:
第一个for循环,是n/m组,包含了n整除m的情况,以及n大于m,但n不整除m的情况;
用一个变量c每次循环逐次加2,代表了一个有序的偶数序列;
S存储,每m个偶数的和,所以s在每次小循环前要清零;
下面if里面是讨论,n小于m和n大于m且n不整除的情况;
当n大于m且不整除m时,执行if上面的循环且接着执行if里面的,c的值是for循环结束时的值,当n小于m时,不执行上面的for循环,c的值从0开始,符合题意,最后输出结果;
每组输完之后,换行再输入下一组数据。
Problem 3
题意:
有一头母牛,它每年年初生一头小母牛。每头小母牛从第四个年头开始,每年年初也生一头小母牛。请编程实现在第n年的时候,共有多少头母牛。
思路:
用递推公式,先把前几年写出来找找规律,递推式要有递推的基础。
注意点:
第n年,在这个年头还没有出生的小牛,比如,第二年,有两头牛,是老母牛和第一个年头出生的小牛。
代码:
#include <cstdio>
int a[60];
int main()
{
int n;
a[1] = 1;
a[2] = 2;
a[3] = 3;
a[4] = 4;
for(int i=5;i <= 60;i++)
{
a[i] = a[i-1] + a[i-3];
}
while(scanf("%d",&n)!= EOF)
{
if(n==0)
{
break;
}
else
{
printf("%d\n",a[n]);
}
}
return 0;
}
题解:
先定义一个数组,找到a【1】a【2】a【3】a【4】的值,就是前4年的牛数=年数,从第五年开始,前面的小牛开始生小牛了,且找到规律为,第n年的牛数为,前一年的牛数加前三年的牛数。
或者也可以这样理解,第n年的牛数为,前一年的牛数+前三年的牛生的牛。
Problem 4
题意:
输入n个整数,按照绝对值从大到小排序后输出。题目保证对于每一个测试实例,所有的数的绝对值都不相等。
思路:
定义两个数组,一个是用来保存原来的数据,另一个用来保存取绝对值后的数据。
注意点:
输出的时候,最后一个数据之后无空格
代码:
#include<iostream>
#include<math.h>
#include<algorithm>
using namespace std;
int a[101];
int b[101];
int main()
{
int n,i,c,k;
while(cin>>n)
{
if(n==0)
{
break;
}
for(i=0;i<n;i++)
{
cin>>c;
a[i]=c;
c=abs(c);
b[i]=c;
}
for(i=0;i<n;i++)
{
for(k=0;k<n;k++)
{
if(b[k+1]>b[k])
{
swap(b[k+1],b[k]);
swap(a[k+1],a[k]);
}
}
}
for(i=0;i<n-1;i++)
{
cout<<a[i]<<" ";
}
cout<<a[n-1]<<endl;
}
return 0;
}
题解:
因为要用到swap 所以头文件要调用#include<algorithm>;
输入原数据,此种类型的题,定于两个数组,一个保存原始数据,一个存储取绝对值后的数据;
利用循环排列取绝对值后的数据的大小,再用一个变量表示要交换的下标,因为是从大到小排序,所以当b【k+1】大于b【k】时,交换它俩的顺序,同时交换a【k+1】与a【k】的位置,因为,b【k】代表a【k】取绝对值后的数;
最后输出a【i】,而最后一个数据之后不输出空格,所以单独拿出输出。
Problem 5
题意:
有n个整数,已经按照从小到大顺序排列好,现在另外给一个整数x,请将该数插入到序列中,并使新的序列仍然有序。
每组数据由两行组成,第一行是n和m,第二行是已经有序的n个数的数列
思路:用for循环找到a[i]中第一个比它的数,那么这个数前的数都比m小,这个数后的数都比m大,则x插到这里。
注意点:最后一个数据之后无空格,所以要单独输出。
代码:
#include<iostream>
using namespace std;
int a[101];
int main()
{
int n,m,i,j;
while(cin>>n>>m)
{
for(i=0;i<n;i++)
{
cin>>a[i];
}
if((m==0)&&(n==0))
{
break;
}
for(i=0;i<n;i++)
{
if(m<a[i])
{
break;
}
}
for(j=0;j<i;j++)
{
cout<<a[j]<<" ";
}
cout<<m<<" ";
for(j=i;j<n-1;j++)
{
cout<<a[j]<<" ";
}
cout<<a[n-1]<<endl;
}
return 0;
}
题解:
先定义一个数组,里面是键盘输入的从大到小排列有序的数据;
如果m和n同时为0时,则跳出循环;
用for循环找到第一个比m大的数a【i】出循环;
按顺序输出a【i】前的,再输出x,再按顺序输出a【i】之后的数据。
Problem 6
题意:
请写一个程序判断读入的字符串是否是“回文”, 输入包含多个测试实例,输入数据的第一行是一个正整数n,表示测试实例的个数,后面紧跟着是n个字符串。
思路:
定义一个字符串数组,用一个变量表示字符串的长度,i从前j从后判断字符是否相等
注意点:
字符数组的使用,以及strlen表示字符串的长度。
代码:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
int n,l,i,j;
char s[100];
cin>>n;
while(n--)
{
cin>>s;
l=strlen(s);
i=0,j=l-1;
while(i<j)
{
if(s[i]!=s[j])
{
break;
}
i++;
j--;
}
if(i>=j)
{
cout<<"yes"<<endl;
}
else
{
cout<<"no"<<endl;
}
}
return 0;
}
题解:
因为下面用到strlen 所以头文件要用#include<cstring>;
定义字符数组要用char【】;
While循环中的表示,输入一个字符串,判断正读与反读的相同位置的元素是否相等,如果不等,则跳出循环,执行下面的语句,如果相等,在继续判断,直到i=j时,当字符串为奇数长度时,i=j,即到中间那个单独的数,当字符串为偶数长度时,i=j,又判断回去了;
最后判断,如果跳出时,i大于等与j,则为回文。
Problem 7
题意:
A-B求的是两个集合的差,就是做集合的减法运算。
每组输入数据占1行,每行数据的开始是2个整数n(0<=n<=100)和m(0<=m<=100),分别表示集合A和集合B的元素个数,然后紧跟着n+m个元素,前面n个元素属于集合A,其余的属于集合B. 每个元素为不超出int范围的整数,元素之间有一个空格隔开.
思路:这其实是一个查重,去重的题,思路很简单。
注意点:集合的差的运算,A-B,就是A减去A和B的交集。
代码:
#include<iostream>
#include<algorithm>
using namespace std;
int a[101];
int b[101];
int main()
{
int m,n,i,j,k,g;
while(cin>>n>>m)
{
k=0;
if((m==0)&&(n==0))
{
break;
}
for(i=0;i<n;i++)
{
cin>>a[i];
}
for(j=0;j<m;j++)
{
cin>>b[j];
}
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
if(a[i]==b[j])
{
k+=1;
a[i]=-1;
}
}
}
if(k==n)
{
cout<<"NULL";
}
else
{
sort(a,a+n);
for(i=0;i<n;i++)
{
if(a[i]>0)
{
cout<<a[i]<<" ";
}
}
}
cout<<endl;
}
return 0;
}
题解:定义两个数组,为两个集合里的元素,当两个数组相等时,就是两个数组的交集里的元素。令这些交集里的元素为负数,最后判断a这个数组是不是大于0,如果大于零的话输出,即为A的减去B和A的交集。
Problem 8
题意:
求A^B的最后三位数表示的整数。
A^B的含义是“A的B次方”
思路:
用循环语句来求A的B次方。
注意点:
要定义为long long int 因为数据比较大
代码:
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
long long int A,B,x,i;
while(cin>>A>>B)
{
x=1;
if((A==0)&&(B==0))
{
break;
}
for(i=0;i<B;i++)
{
x=(A*x)%1000;
}
cout<<x<<endl;
}
return 0;
}
题解:
当A与B都为0的时候,跳出循环。
用一个循环语句,但是要注意,由于乘积最后的结果太大,所以每次只保留最后三位数。最后,输出结果。
Problem 9
题意:
而284的所有真约数为1、2、4、71、 142,加起来恰好为220。人们对这样的数感到很惊奇,并称之为亲和数。一般地讲,如果两个数中任何一个数都是另一个数的真约数之和,则这两个数就是亲和数。
思路:
先找出