1.TB
求给定范围内的水仙花数(“水仙花数”是指一个三位数,它的各位数字的立方和等于其本身,比如:153=1^3+5^3+3^3)
解题思路:循环处理给定范围内的各数并求各数各位的立方根之和
细节处理:输出时注意空格与转行,当遇到第一个水仙花数时,输出该数,从第二个开始,先输出一个空格,在输出水仙花数
原码:
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int i,n,m,s;
while(cin>>m>>n)
{
s=0;
for(i=m;i<=n;i++)
{
if(pow((double)(i%10),3)+pow((double)(i/100),3)+pow((double)((i%100)/10),3)==i)
{
if(s==0)
{
cout<<i;
s++;
}
else if(s!=0)cout<<" "<<i;
}
}
if(s==0)cout<<"no"<<endl;
else cout<<endl;
}
return 0;
}
总结:1.使用pow时不要忘记头文件
#include <math.h>2.注意pow(double,int)不要忘记使用强制转换3.注意空格与转行的使用否则易出现Presentation Error
2.TD
对于表达式n^2+n+41,当n在(x,y)范围内取整数值时(包括x,y)(-39<=x<y<=50),判定该表达式的值是否都为素数。
解题思路:编写一个求素数的函数,然后循环判断y(n)是否为素数,如是则使j++,循环结束后若j==y-x+1则都为素数
细节处理:求函数的素数时循环到sqrt(x)即可,以防超时
原码:
#include <iostream>
#include <cmath>
#include <math.h>
using namespace std;
int prime(int x)
{
int i, n;
n = sqrt(x);
for(i = 2; i <= n; i++)
{
if (x % i == 0)
return 0;
}
return 1;
}
int main()
{
int x,y,j,n,h;
while(cin>>x>>y)
{
j=0;
if(x==0&&y==0)break;
else
{
for(n=x;n<=y;n++)
{
h=(int)pow((double)n,2)+n+41;
if(prime(h))
j++;
}
if(j==y-x+1)cout<<"OK"<<endl;
else
cout<<"Sorry"<<endl;
}
}
return 0;
}
总结:math.h是C语言的头文件,在C++中用math.h也可。使用#include <cmath>必须声明在std命名空间:using namespace std;其中的函数和使用方法相同。使用sqrt时须有这头文件,判断素数,求10阶以下阶乘等用编写函数的方法更简单
3.TF
有一个长度为n(n<=100)的数列,该数列定义为从2开始的递增有序偶数,现在要求你按照顺序每m个数求出一个平均值,如果最后不足m个,则以实际数量求平均值。编程输出该平均值序列。
思路:循环里面放个循环,内循环是要不断加数列中的偶数,同时用一个q记录加法次数当q整除m时结束内循环,将加法结果赋值给外循环的数组。
细节处理:如果最后剩下不足m个数,则剩n%m个,将其相加赋给数组中的第(n/m)+1个地址。
原码:#include <iostream>
using namespace std;
int main()
{
int i,j,n,m,q,z;
double s[101]={0};
while(cin>>n>>m)
{
z=0;
j=0;
q=0;
for(i=1;i<=n/m;i++)
{
q=q+1;
j+=2;
for(;;j+=2,q++)
{
s[i]+=j;
if(q%m==0)break;
}
}
if(n%m!=0)
{
for(j=j+2;j<=2*n;j+=2)
{
s[(n/m)+1]+=j;
z++;
}
for(i=1;i<=(n/m)+1;i++)
{
if(i==1)cout<<s[i]/m;
else if(i<=n/m&&i!=1)
cout<<" "<<s[i]/m;
else if(i==n/m+1)
cout<<" "<<s[i]/z;
}
}
else if(n%m==0)
{
for(i=1;i<=n/m;i++)
{
if(i==1)cout<<s[i]/m;
else cout<<" "<<s[i]/m;
}
}
cout<<endl;
for(i=1;i<=(n/m)+1;i++)
s[i]=0;
}
return 0;
}
4.TH
有一头母牛,它每年年初生一头小母牛。每头小母牛从第四个年头开始,每年年初也生一头小母牛。请编程实现在第n年的时候,共有多少头母牛?
解题思路:第四年时,共有成年小羊一岁二岁三岁各一只之后的每年都是前一年中的成年小羊+=3岁小羊
;3岁=2岁;2岁=1岁;1岁=成年小羊个数与3岁小羊相加个数。
细节处理:注意赋值时的顺序,还有付初值时要再循环内进行
原码:#include <iostream>
using namespace std;
int main()
{
int a,b,c,d,n,j;
while(cin>>n)
{
a=1;
b=1;
c=1;
d=1;
if(n<=4&&n!=0)cout<<n<<endl;
else if(n==0)break;
else
{for(j=5;j<=n;j++)
{
d+=c;
c=b;
b=a;
a=d;
}
cout<<a+b+c+d<<endl;}
}
return 0;
}
5.TL
“回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。请写一个程序判断读入的字符串是否是“回文”。
输入包含多个测试实例,输入数据的第一行是一个正整数n,表示测试实例的个数,后面紧跟着是n个字符串。
如果一个字符串是回文串,则输出"yes",否则输出"no".
解题思路:循环比较字符串中对称未知的字符是否相同,若不相同则结束循环输出no,否则继续,若正常结束循环则输出yes
细节:将输入的字符串放到数组里面,用strlen(a
)统计字符串中字符数然后将对称的两位比较
文件cstring,和string.h对应,c++版本的头文件,包含比如strcpy之类的字符串处理,cstdio是将stdio.h的内容用C++头文件的形式表示出来。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int main()
{
int n,i,m,j,z;
char a[110];
cin>>n;
for(i=0;i<n;i++)
{
z=0;
cin>>a;
m=strlen(a);
for(j=0;j<m/2;j++)
if(a[j]!=a[m-j-1])z+=1;
if(z==0)cout<<"yes";
else
cout<<"no";
cout<<"\n";
}
return 0;
}
6.TO
集合的减法运算,A-B就是将A中属于B的元素去除
解题思路:将A中的元素拿到B中去找相同的,若找到,结束该元素的比对且继续比对下一个,若找不到则将其放到一个容器中,最后输出容器中的元素。
细节:如何输出容器中的元素。开头有set<int>::iterator z;
结尾有for(z=a.begin();z!=a.end();z++)
cout<<*z<<" ";
cout<<"\n";
注意一次完整循环结束后要a.clear();还要判断a是否为空a.empty()
原码:#include <iostream>
#include <set>
using namespace std;
set<int>::iterator z;
set<int>a;
int main()
{
int n,m,b[110],c[110],i,j;
while(cin>>n>>m)
{
if(n==0&&m==0)break;
a.clear();
for(i=0;i<n;i++)cin>>b[i];
for(j=0;j<m;j++)cin>>c[j];
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
if(b[i]==c[j])break;
if(j==m)a.insert(b[i]);
}
if(a.empty())cout<<"NULL";
else
for(z=a.begin();z!=a.end();z++)
cout<<*z<<" ";
cout<<"\n";
}
return 0;
}
7.TP
求A^B的最后三位数表示的整数。
说明:A^B的含义是“A的B次方”
(1<=A,B<=10000)
解题思路:若用pow((double)A,B)不行,这样数可能会很大,编写时易出错,该题只要最后三位,故应用循环将A*A*A......一个个的相乘,然后除以1000取余。
细节:每次相乘的结果若超过3位则只保留最后三位
原码:#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int a,b,A,B;
while(cin>>A>>B)
{
b=A;
if(A==0&&B==0)break;
else
{
for(a=0;a<B-1;a++)
b=b*A%1000;
}
cout<<b<<"\n";
}
return 0;
}
8.TR
有一楼梯共M级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第M级,共有多少种走法?
解题思路:一开始想的是1.将M阶用循环划分成有限个1与2相加,将每种划分方式的不同走法数量相加,即sum(1与2一共个数和的阶乘/(1个数的阶乘*2个数的阶乘))。该做法只能到24阶与答案相符,如果按这种思路,将24阶写出来,则会发现有规律,2.规律是:从第三阶开始前两项相加的后一项。比如走第五阶时,先走一步,剩下的按走4阶的算;若先走两步,则剩下的按走三阶的算。(不明白两种做法为何到24阶以后就不一样了)
细节处理:由于在第一阶起步,将在第一阶时记为一,2阶记为1,从第三阶开始循环。求阶乘时10阶以下可用函数。
正确:#include <iostream>
using namespace std;
int main()
{
int M,N,i,a[50],j;
cin>>N;
for(i=0;i<N;i++)
{
cin>>M;
a[1]=1;
a[2]=1;
for(j=3;j<=M;j++)
a[j]=a[j-1]+a[j-2];
cout<<a[M]<<endl;
}
return 0;
}
错误(前24):
#include <iostream>
using namespace std;
int main()
{
int M,N,i,s,m,n,z,k,j;
cin>>N;
for(i=0;i<N;i++)
{
s=0;
cin>>M;
for(n=0;n<=M-1;n+=2)
{
m=M-n-1;
if(n==0||m==0)s+=1;
else if(m!=0&&n!=0)
{
z=1;
for(j=m+1;j<=m+n/2;j++)
z*=j;
for(k=2;k<=n/2;k++)
z/=k;
s+=z;
}
}
cout<<s<<endl;
}
return 0;
}
9.TU手机号
手机号另外拥有一个短号。假设所有的短号都是是 6+手机号的后5位输出该短号。
分析:将其看做一个数,将后5位在输出6后输出;
或加600000/(号码数+600000)%100000-(号码数-600000)/100000*100000。
细节:用第一种方法时,注意0的输出。若直接用号码数%100000,则一开始0的输出受限,故使用以上方法。设手机号变量时要用long long int。
#include <iostream>
#include <cstdio>
#include <math.h>
using namespace std;
int main()
{
int N,j,i;
long long int a[210];
cin>>N;
for(i=1;i<=N;i++)
{
cin>>a[i];
for(j=5;j>=1;j--)
{if(j==5)
cout<<'6'<<a[i]%(int)pow((double)10,j)/(int)pow((double)10,(j-1));
else
cout<<a[i]%(int)pow((double)10,j)/(int)pow((double)10,(j-1));
}
cout<<"\n";
}
return 0;
}
10.V
有如下方程:Ai = (Ai-1 + Ai+1)/2 - Ci (i = 1, 2, 3, .... n).
若给出A0, An+1, 和 C1, C2, .....Cn.
请编程计算A1 = ?对于每个实例,首先是一个正整数n,(n <= 3000); 然后是2个数a0, an+1.接下来的n行每行有一个数ci(i = 1, ....n);输入以文件结束符结束。
思路:已知a0与an,求a1,先将a1记为0,由公式循环求出一个an’,再将a1记为1,由公式循环求出一个bn。由其关系求得a1。
细节:其几者的关系位z=(a[n+1]-a’[n+1])/(b[n+1]-a’[n+1]);
#include <iostream>
#include <cstdio>
#include <iomanip>
using namespace std;
int main()
{
int n,i,j;
double a[3010],c[3010],b[3010],z,d[3010];
while(cin>>n)
{
cin>>a[0]>>a[n+1];
for(i=1;i<=n;i++)
cin>>c[i];
b[0]=a[0];
b[1]=0;
for(j=0;j<=n-1;j++)
{
b[j+2]=2*b[j+1]-b[j]+2*c[j+1];
}
d[0]=a[0];
d[1]=1;
for(j=0;j<=n-1;j++)
{
d[j+2]=2*d[j+1]-d[j]+2*c[j+1];
}
z=(a[n+1]-b[n+1])/(d[n+1]-b[n+1]);
printf("%.2lf",z);
cout<<"\n";
}
return 0;
}
11.W不吉利的数字为所有含有4或62的号码。例如:
62315 73418 88914
都属于不吉利号码。但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列。
你的任务是,对于每次给出的一个牌照区间号,推断出交管局今次又要实际上给多少辆新的士车上牌照了。
思路:找一个区间的数的每一位是否为4,若是,则该区间的数减一;可从后往前两位两位的找62,若有,则该区间数减一。
细节:每次除以10取余数检查是否为4,然后除以100取余数检查是否为62,检查完了将该数除以10取商赋值给自己
#include <iostream>
#include <iomanip>
#include <cstdio>
using namespace std;
int js(int a)
{
while(a!=0)
{
if(a%10==4||a%100==62)return 0;
a=a/10;
}
return 1;
}
int main()
{
int n,m,i;
while(cin>>n>>m)
{
if(n==0&&m==0)break;
int s=0;
for(i=n;i<=m;i++)
if(js(i)!=0)
s+=1;
cout<<s<<endl;
}
return 0;
}
12.A
悟空吃桃第一天悟空吃掉桃子总数一半多一个,第二天又将剩下的桃子吃掉一半多一个,以后每天吃掉前一天剩下的一半多一个,到第n天准备吃的时候只剩下一个桃子。聪明的你,请帮悟空算一下,他第一天开始吃的时候桃子一共有多少个呢?
思路分析:用公式循环求解记前一天桃子数共z个后一天为x个,则z=(x+1)*2;
细节:注意循环次数是n-1次,而非n。
#include <iostream>
using namespace std;
int main()
{
int n,x;
while(cin>>n)
{
x=1;
int i;
for(i=1;i<n;i++)
x=(x+1)*2;
cout<<x<<endl;
}
return 0;
}
13.C在一个平面内有两个点,求两个点分别和原点的连线的夹角的大小。
注:夹角的范围[0,180],两个点不会在圆心出现。输入数据的第一行是一个数据T,表示有T组数据。
每组数据有四个实数x1,y1,x2,y2分别表示两个点的坐标,这些实数的范围是[-10000,10000]。
思路:用求夹角的公式;x1*x2+y2*y1=模*模*cos角
细节:该公式求出来的角为弧度制1°=π/180 rad;arccos在此记为acos,须有头文件#include <math.h>
代码:#include <iostream>
#include <cstdio>
#include <math.h>
#include <cmath>
using namespace std;
#define p 3.1415926;
int main()
{
double x1,x2,y1,y2,z,a,b,c=180.0;
int i,T;
cin>>T;
for(i=1;i<=T;i++)
{
cin>>x1>>y1>>x2>>y2;
b=x1*x2+y1*y2;
a=sqrt(x1*x1+y1*y1)*sqrt(x2*x2+y2*y2);
z=c*acos(b/a)/p;
printf("%.2lf",z);
cout<<"\n";
}
return 0;
}
14.H把一个字符三角形掏空每行包含一个字符和一个整数n(0<n<41),不同的字符表示不同的花纹,整数n表示等腰三角形的高。显然其底边长为2n-1。如果遇到@字符,则表示所做出来的样板三角形已经够了。
思路:找规律,每行的n+1-i或n-1+i列都应该输出自符
在n+1-i或n-1+i列中输出空格
细节,列数要从1开始,共2n-1行,注意空格与回车的使用。要求两个三角形中间空一行
代码:#include <iostream>
using namespace std;
int main()
{
int n,i,j,s=0;
char a;
while(cin>>a)
{
if(a=='@')break;
if(s!=0)cout<<"\n";
cin>>n;
s+=1;
for(i=1;i<=n;i++)
{
for(j=1;j<=n-1+i;j++)
if(i==n)cout<<a;
else
{
if(j==n+1-i||j==n-1+i)cout<<a;
else
cout<<" ";
}
cout<<"\n";
}
}
return 0;
}
15.S
有一只经过训练的蜜蜂只能爬向右侧相邻的蜂房,不能反向爬行。请编程计算蜜蜂从蜂房a爬到蜂房b的可能路线数。
其中,蜂房的结构如下所示。
思路:a-b为1时,路线总数为1;a-b为2时,路线总数为2;a-b为3时,路线总数为3;......随着a-b的增大,若将小蜜蜂不动时的路线记为1,则当a-b大于3时后一项结果为前两项结果相加。
细节:将小蜜蜂不动时的路线记为1。
代码:#include <iostream>
using namespace std;
int main()
{
int a,b,N,i,j;
long long int c[55];
cin>>N;
for(i=0;i<N;i++)
{
cin>>a>>b;
c[0]=1;
c[1]=1;
for(j=2;j<=b-a;j++)
c[j]=c[j-1]+c[j-2];
cout<<c[b-a]<<endl;
}
return 0;
}
总结
这段时间学到了很多,比如说使用acos时要有头文件#include<math.h>,map和set容器,之前遇到有关自负的提示不知道从哪下手,现在知道题目给出一些字符要求求不同字符串数目时可以set<string>a,然后将给出字符串插入其中a.insert(b),该容器中不会有相同的元素,最后统计集合长度啊a.size()。求回文串时先用一个char定义一个数组,然后将一个字符串传入数组中,用strlen(a)统计a占用了几个地址,然后从两边比较即可。还有一个印象比较深的题,当时使用了函数编写求n阶阵,但n一旦很大,数就不准,当n很大时函数存不了就溢出了。函数虽然能节省时间并且好用,但不能乱用。这段时间通过做题有个很大的感受是拿到题后先不要急着做,想想想,玩一想到简便方法了呢。还要注意定义变量时long long int double等的使用。有个题涉及到匈牙利算法,就是坐过山车的题,大概思路有了,但是不知道怎么做,比如说女1可以和男1一起,就先把他两放一起,女2可以和男2一起,那也先把他两个放一起,但女3只想和男1一起,那就看看已经和男1配对的女1能否在另找他人,若发现女1能和男2一起,那再看和男2一起的女2能否在另找他人,恰好女2可以和男3一起,这样一来女2与男3,女1与男2,女3与男1。还知道了这可求是每条线都至少有一个端点的点的最小个数。做题时一定要严格按照题目做题,多多注意空格与回车的使用。使用数组时要注意范围,不要发生溢出或数组开太大的问题。通过这些天的学习,可能只是学到了一点皮毛,又在做题时绝望过,但就是在做到不会的题时,才能学到更多,成长给多,有时候就想如果把老师讲的都记住,那我会的东西会更多,然后就去看记得老师讲过的东西,真的是管用的,老师当时讲的可能当时听懂了,但之后没再去深入思考,那很快就会忘,我希望以后我会抽空学点儿,因为自己会的太少了,但它好像有是有用的,这个不能丢。