一、课设一 problem A
题意:在一定范围内将不同小范围内的数转化成不同的等级,不在范围的数不做转化。
解题思路:采用if语句实现不同范围等级的转化,使用输入方便的c++语言。
细节处理:注意要换行,还有使用双引号引起字符。
源代码:
#include<iostream>
using namespace std;
#include<stdio.h>
#include<math.h>
int main()
{
int a;
char A,B,C,D,E;
while (cin>>a)
if(a>=90&&a<=100) cout<<"A"<<endl;
else
if(a>=80&&a<=89) cout<<"B"<<endl;
else
if(a>=70&&a<=79) cout<<"C"<<endl;
else
if(a>=60&&a<=69) cout<<"D"<<endl;
else
if(a>=0&&a<=59) cout<<"E"<<endl;
else
if(a<0||a>100) cout<<"Score is error!"<<endl;
}总结:这种类型的问题是较为简单的划定范围转化问题,被划定的范围数量已知且数目较少,易于一一列举出来。
二、课设一 problem B
题意:给予水仙花数的说明,设计程序来判断一个数是否为水仙花数。
解题思路:主要把握好“水仙花数”是指一个三位数,它的各位数字的立方和等于其本身。然后想办法拆出这三位数的每一位上的数,把它们的立方和相加判断即可。
细节处理:注意要求水仙花数的范围,还有要按照从小到大的顺序输出,涉及到排序问题,在代码中应加入排序的处理。还有,要保证输入的数是三位数,其他位数的都是不合法的。
源代码:
#include <iostream>
using namespace std;
int main()
{
int m,n,i;
while (cin>>m>>n)
{
int x=0;
int y[1010];
for(i=m;i<=n;i++)
{
int a=0,b=0,c=0;
a=i/100;
b=i/10%10;
c=i%10;
if(i==a*a*a+b*b*b+c*c*c)
{
y[x]=i;
x++;
}
}
if(!x) cout<<"no"<<endl;
else
{
for(int j=0;j<x;j++)
{
cout<<y[j];
if(j<x-1) cout<<" ";
}
cout<<endl;
}
}
return 0;
}总结:这道题主要练习的是拆分数,以及数的排序问题,源代码中的最后一部分就是对排序的解决,可以说,本题中拆分数并不难,难度在于如何排序。
三、课设一 problem C
题意:将n个数中所有奇数的乘积求出来。
解题思路:首先,要解决如何输入一组数据,这个时候就该考虑使用数组了。然后就是找出其中的奇数,由于是一组未知数量的数据,所以应该使用循环结构。奇数我们都知道,就是除以二余一的数,然后将筛选出来的数(也就是所有的奇数)再次使用循环进行相乘。
细节处理:注意循环的次数,以及题目中的输出样例都是一行一行的,所以一定要记得换行!
源代码:
#include<stdio.h>
int main()
{
int n, i, a[1000], s = 1;
while (scanf("%d", &n) != EOF)
{
for (i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
}
for (i = 1; i <= n; i++)
{
if (a[i] % 2 != 0)
s = s * a[i];
}
printf("%d", s);
printf("\n");
s = 1;
}
return 0;
}总结:本题融合了数组、循环的知识,二者的结合能够解决一组数据的处理问题,不再是已知数量的数据,使得处理的范围变大,程序的应用度广泛。
四、课设一 problem F
题意:简单来讲是求平均值,但是附加了条件:数列是从2开始递增的偶数列,然后每m个数求出一个平均值,不足m个的按实际计算,然后依次输出。
解题思路:使用循环语句,先将数组表示出来,再依次进行分组求平均值,然后输出。
细节处理:注意循环的次数,以及空格的输出,还有,注意换行。
源代码:
#include<stdio.h>
#include<iostream>
using namespace std;
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
int temp=0,sum=0,i,t=0,h1,h2;
for(i=1;i<=n;i++)
{
sum+=2*i;
t++;
if(t==m)
{
if(temp==0) temp=1;
else cout<<" ";
h1=sum/m;
cout<<h1;
sum=0;
t=0;
}
}
if(t!=0)
{
if(temp==0) temp=1;
else cout<<" ";
h2=sum/t;
cout<<h2;
}
cout<<endl;
}
}总结:本题是给出了数列的特征,需要我们自己将数列输出,然后进行分组求平均值。用到了循环和if语句,两者结合时的问题的解决变得简单。
五、课设一 problem G
题意:评分时去掉最高分和最低分,求其平均值。
解题思路:先将所有评分输入,再进行排序,去掉最高分和最低分,将剩下的数求平均值。
细节处理:一组数据的输入,使用数组,然后再对这组数据进行排序,排序是使用基本的排序方法即可,即两两对比,最后去掉最高和最低,求平均值,再输出。尤其要注意,要求输出的数保留两位小数,一定要在最后输出时加上这个条件!
源代码:
#include<stdio.h>
int main()
{
int n, i, j, a[101], l;
double average, s = 0;
while (scanf("%d", &n) != EOF)
{
for (i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
}
for (j = 1; j <= n - 1; j++)
{
for (i = 1; i <= n-j; i++)
{
if (a[i] < a[i + 1])
{
l = a[i];
a[i] = a[i + 1];
a[i + 1] = l;
}
}
}
for (i = 1; i <= n; i++)
{
s += a[i];
}
average = (s - a[1] - a[n]) / (n - 2);
printf("%.2lf", average);
s=0;
printf("\n");
}
return 0;
}总结:这个题目还是涉及到排序问题,不同的是,加了点东西,需要将排序后的最大值和最小值去掉,也就是将排序后的数的最前面和最后面的数去掉,然后再将剩下的数加起来除以原来输入的数的个数减去二即可。
六、课设一 problem I
题意:将n个数按照绝对值由小到大进行排序。
解题思路:先将输入的n个数都取绝对值,可以用if语句,也可以使用abs函数,在这里我选用的是使用函数的方式。然后将它们的绝对值进行排序,排序时可以使用两两比较的办法,也可以使用sort函数,我选用的是两两比较的方法。
细节处理:强调多组数据的输入,要用while语句,进行两两比较时,选用循环语句,尤其注意,题目要求输出时两个数之间要用空格隔开,一定要输出空格,最后还是注意换行的问题,要加endl(c中加/n).
源代码:
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int a,i,j,t;
while (cin>>a&&a)
{
int b[a];
i=0;
while (i<a)
cin>>b[i++];
for(i=0;i<a;i++)
for (j=0;j<a-i-1;j++)
{
if (abs(b[j])<abs(b[j+1]))
{
t=b[j];
b[j]=b[j+1];
b[j+1]=t;
}
}
for(i=0;i<a-1;i++)
cout<<b[i]<<" ";
cout<<b[i]<<endl;
}
return 0;
}总结:本题中有两个点都可以使用两种方法解决(我所了解到的知识来说),关键时刻要记住函数的作用和使用方法,我当时做的时候就是忘记了sort函数的头文件,才使用了两两相比的办法。还有,循环语句真的是特别好用,能减少很多工作量。
七、课设一 problem J
题意:在已经由小到大排好的序列中,插入一个数,使新的序列仍然有序。
解题思路:直接把数插入序列,然后将此数与数列中的数两两相比,进而得到新的序列。细节处理:题目中明确指出,“n和m同时为0标示输入数据的结束,本行不做处理。”注意到这个条件,故我在程序中使用了if语句,当它们同时为零时,直接跳出来。还要注意输出的数每两个之间都有空格,其余的都是正常的条件,正常处理即可。
源代码:
#include<iostream>
using namespace std;
main()
{
int i,m,n,a[1010];
while(cin>>n>>m)
{
if(m==0&&n==0)
break;
for(i=0;i<n;i++)
cin>>a[i];
if(m>a[n-1])
a[n]=m;
else
{
i--;
while(a[i]>m)
{
a[i+1]=a[i];
i--;
}
a[i+1]=m;
}
for(i=0;i<=n;i++)
{
cout<<a[i];
if(i<n) cout<<' ';
else cout<<endl;
}
}
}总结:这和课堂上讲的区别在于加了一个,当n和m同时为零时,不做处理,一定要认真审题,不能因为讲过,就眼高手低。插入数据的问题,这个题带给我的收获是,一定要认真审题。
八、课设一 problem L
题意:判断一个字符串是不是回文串。
解题思路:首先要明确回文串的定义,即正读和反读都一样的字符串,那么就可以判断正数第n个字符和倒数第n个字符是否一样即可。
细节处理:注意多组数据测试,使用循环语句最为方便,还有要输出yes或no,这都属于字符串,需要用双引号引起来。
源代码:
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
int fun(char a[])
{
int i,m,t=1;
m=strlen(a)-1;
for(i=0;i<=m;m--,i++)
{
if(a[i]!=a[m])
{
t=0;
break;
}
}
return t;
}
int main()
{
char a[20];
int i,n;
cin>>n;
for(i=0;i<n;i++)
{
cin>>a;
if(fun(a)==0)
cout<<"no"<<endl;
else
cout<<"yes"<<endl;
}
return 0;
}
总结:在本题中我使用了自定义的函数,第一次使用,有些手生,还在其中使用了strlen函数,函数的使用也是解决问题的一大利器。回文串是之前在oj里做过的题,虽然做过,但是这次尝试了不一样的方法,收获也不一样。
九、课设一 problem N
题意:A、B相加的问题,但是是时间的相加。
解题思路:输入六个数,前三个属于A组,后三个属于B组,然后依次按照时、分、秒分别相加,并且从最小的单位开始加。
细节处理:时间的范围是0~59,所以从最小的单位开始加,满六十就要向前一位进一,否则不符合事实,也就会得到错误答案。还要注意,空格问题,每两位数之间一定要加空格。
源代码:
#include<iostream>
using namespace std;
int ah,am,as,bh,bm,bs;
int main()
{
int n,i,ch,cm,cs;
while(cin>>n)
{
for(i=0;i<n;i++)
{
ah=0,am=0,as=0,bh=0,bm=0,bs=0;
cin>>ah>>am>>as>>bh>>bm>>bs;
cs=as+bs;
ch=ah+bh;
cm=am+bm;
cm=cm+cs/60;
ch=ch+cm/60;
cm=cm%60;
cs=cs%60;
cout<<ch<<" "<<cm<<" "<<cs<<endl;
}
}
}
总结:时分秒的相加,应当注意范围问题,每个问题的数据都有不同的背景,应当根据实际背景做出正确的判断。
十、课设一 problem P
题意:求“A的B次方”的最后三位数表示的整数。
解题思路:先是使用if语句将a、b同时为零的结果表示出来,接下来就是他们不同时为零的情况了,使用循环语句,循环b次,得到所需值。
细节处理:每组的输出占一行,注意使用endl换行,输出最后三位数使用的循环语句要注意,是x*=(a%1000); x%=1000;,这一步很重要。
源代码:
#include<iostream>
using namespace std;
int main()
{
int a,b;
while(cin>>a>>b)
{
if(a==0&&b==0)
break;
int x=1;
for(int i=1;i<=b;i++)
{
x*=(a%1000);
x%=1000;
}
cout<<x<<endl;
}
}
总结:此题目要求求出a的b次方的最后三位的整数,重要的一步就是最后的x的循环,这个地方是整个程序的灵魂,准确使用恰当的算法,才能使得问题更好解决。
十一、课设一 problem R
题意:有一楼梯共M级,刚开始时在第一级,每次只能跨上一级或二级,要走上第M级,共有多少种走法。
解题思路:每走一步都有两种选择,跨一阶或者两阶,使用双重循环语句进行计算。
细节处理:仅仅定义int是不够用的,所以应该定义long long int更好一些,还是要注意换行问题。
源代码:
#include<iostream>
using namespace std;
long long int a[50];
int main()
{
int n,m,i,j;
cin>>n;
for(i=1;i<=n;i++)
{
cin>>m;
a[2]=1;
a[3]=2;
for(j=4;j<45;j++)
{
a[j]=a[j-1]+a[j-2];
}
cout<<a[m]<<endl;
}
}
总结:题目猛的一看很难懂,实际分析起来也是有难度的,发现这是一个递推问题,本题使用到了双重循环,结合数组的知识,找出递推关系,做出算法进行操作。最后再注意一下细节的处理即可。
十二、课设一 problem U
题意:短号都是是 6+手机号的后5位, 现在给一个11位长的手机号码,找出对应的短号。
解题思路:将输入号码的后五位提出来,然后在它的最前面加上6即可。
细节处理:11位,输入长度较大,输入时注意定义成long long,然后使用c++输入输出控制精度,注意头文件的添加,应是iomanip。
源代码:
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
int n,i;
long long k,l;
while(cin>>n&&n)
{
for(i=0;i<n;i++)
{
cin>>setprecision(11)>>l;
k=l%100000+600000;
cout<<setprecision(11)<<k<<endl;
}
}
}
总结:本题能学习到的是注意定义的数的范围,还有多组数据的输入,以及c++中关于精度输入输出的表示方法,尤其注意,使用c++限定精度时要加头文件。
十三、课设一 problem X
题意:帮妈妈算买菜花了多少钱。
解题思路:首先是各类产品的名称,需要用字符串来定义,然后将数量与单价的关系找出来用程序表达出来即可。
细节处理:用到了字符串,这是需要注意加上头文件cstring,还有同上题一样的控制精度的问题,需要用setprecision,也不要忘记头文件。
源代码:
#include<iostream>
using namespace std;
#include<cstring>
#include<iomanip>
int main()
{
string name;
double n,m,t=0;
while(cin>>name>>n>>m)
{
t=t+n*m;
}
cout<<fixed<<setprecision(1)<<t<<endl;
}
总结:由于这类实际问题对数的要求较高,所以使用double来定义,单价与数量之间的关系较容易找出来,总的来说问题的难度并不是很大,但是重要的是细致的精度处理问题。
十四、课设二 problem E
题意:把一个偶数拆成两个不同素数的和,有几种拆法呢。
解题思路:首先应明确素数是什么,素数是除了能表示为它自己和1的乘积之外,不能表示为任何其它两个整数的乘积。然后再想怎样把数拆成两个数的和。
细节处理:使用bool类型,用来判断真与假,然后使用循环结构来对一组数据进行处理。
源代码:
#include<iostream>
#include<cmath>
int b[10000000];
bool a[10000000];
using namespace std;
int main()
{
int i,j,m,n,t,w;
while(cin>>n&&n!=0)
{
a[0]=a[1]=false;
for(i=2;i<=n;i++)a[i]=true;
for(i=2;i<=n;i++)
{
if(a[i])
{
for(j=i*2;j<=n;j+=i)
{
a[j]=false;
}
}
}
int w=1;
for(i=2;i<=n;i++)
{
if(a[i])b[w]=i,w++;
}
int y=0;
for(i=1;i<w-1;i++)
{
for(j=i+1;j<w;j++)
{
if(b[i]+b[j]==n) y++;
}
}
cout<<y<<endl;
}
}
总结:这个问题以前遇到过差不多的,这是有几种拆法,并没有让把拆出来的输出,还是比较好处理的,但是仍旧是个复杂的问题。使用到了补充过的bool类型。
十五、课设二 problem H
题意:输出图形。
解题思路:找到题目要求输出的图形的规律,按行和列找出规律即可。
细节处理:题目中说,如果遇到@字符,则表示所做出来的样板三角形已经够了。一定要在程序中体现出来,即为所写while(cin>>ch&&ch!='@'&&cin>>n),具体规律很好找,而且要注意换行,一定要换行,不换的话直接输出一串字符,影响很大。
源代码:
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
int i,j,x,m,n,y,z,q=1;
char ch;
while(cin>>ch&&ch!='@'&&cin>>n)
{
if(q>1) cout<<endl;
x=(2*n-1)/2+1;
y=(n*2-1)/2+1;
z=(n*2-1)/2+1;
for(i=1;i<=n-1;i++)
{
for(j=1;j<=x;j++)
{
if(j<y)cout<<' ';
if(j==y||j==x)cout<<ch;
if(j>y&&j<x) cout<<' ';
}
x++,y--;
cout<<endl;
}
for(i=1;i<=2*n-1;i++)cout<<ch;
cout<<endl;
q++;
}
}
总结:和之前做的循环练习中的主要问题是一样的,就是输出图形问题,这类问题只要找出规律,处理好不同问题的细节即可。