C++程序设计报告

一.水仙花数

1.题意:输出所有在m与n之间的水仙花数(水仙花数:各位数字立方和等于其本身)

2.解题思路:根据水仙花数的定义,可以用暴力破解的方法,使用三重循环,分别代表百位、十位、个位让后来判断是否满足定义,若满足则将这个数放入数组中,最后输出数组即可,若没有,则输出no.

3.细节处理:存水仙花的数组的下标要赋初值,最后输出数组时,循环的上限是sum-1,而不是sum,因为最后sum加了1.

关于格式问题,我得想法是先输入前n-1个(也就是代码中的sum-2),后面紧跟着输出空格,最后第n个(代码中sum-1)单独输出,便可满足题目要求.

4.源代码:

#include

using namespace std;

int main()

{

int a[5];

int i,j,m,n,k,sum,p;

while(cin>>m>>n)

{

    sum=0;

for(i=1;i<10;i++)

{

    for(j=0;j<10;j++)

    {

        for(k=0;k<10;k++)

        {

if(iii+jjj+kkk==100i+10j+k&&(100i+10j+k)>=m&&100i+10j+k<=n)

            {

            a[sum]=100*i+10*j+k;

            sum++;

            }

        }

    }

}

if(sum==0)

cout<<"no";

else

{

for(p=0;p<=sum-2;p++)

cout<<a[p]<<" ";

cout<<a[sum-1];

}

cout<<endl;

}

}

二.判断素数

1.题意:n在(x,y)范围内取值,判断表达式的值是否为都素数。

2.解题思路:为了简化代码,我们可以先定义一个函数prime来判断一个数是否为素数,若为素数,则令变量加一,最后比较这个变量与循环次数的大小,所相等则这个范围全为素数,反之,则至少这个范围内有一个数不是素数.

3.细节处理:判断素数的函数prime在定义时,是用这个数除以2到它的算数平方根,若不然,很有可能会超时.关于次方的表示这里用了pow函数,需要头文件cmath.

4.源代码:

#include

#include

using namespace std;

int prime(int x)

{

int i;

double n;

n=sqrt(x);

for(i=2;i<=n;i++)

{

if(x%i==0)

return 0;

}

return 1;

}

int main()

{

int p,q,x,y,i,s;

while(cin>>x>>y)

{

if(x0&&y0)

break;

else

{

p=0,q=0;

for(i=x;i<=y;i++)

{

p++;

s=pow(i,2)+i+41;

if(prime(s))

q++;

}

if(p==q)

cout<<“OK”<<endl;

else

cout<<“Sorry”<<endl;

}

}

return 0;

}

三.前n项的和

1.题意:1 - 1/2 + 1/3 - 1/4 + 1/5 - 1/6 + …求多项式前n项和.

2.解题思路:这是一道数学常见题型 求上面多项式的和可以

   n

记为为 ∑(1/i)*(-1) ^(i+1),可以通过数学方法利用表达式计算.

i=1

3.细节处理:注意定义求和变量应该用实型double,在for循环中,应该从第二张开始累加,所以对sum的初值应该为1.00,关于正负号问题,可以通过(-1)^i来实现,即上题提到的pow函数可以用解决此类问题.

4.源代码:

#include

#include

#include

using namespace std;

int main()

{

int m,n;

double sum,i,j;

while(cin>>m)

{

for(j=1;j<=m;j++)

{

cin>>n;

sum=1,00;

for(i=2;i<=n;i++)

{

sum+=(1/i)*pow(-1,i+1);

}

printf("%.2f",sum);

cout<<endl;

}

}

return 0;

}

四.偶数列平均值

1.题意:从2开始的偶数列,按顺序每m个数求平均值,最后一组以实际数量求平均。

2.解题思路:先利用将这些偶数列放入数组,然后判断n是否能整除m: 若能整除,则每一组正好m个,所以将每一组数据求和后除以m可以得到这n/m个平均值; 若不能整除,则把后不够m个数单独成组,使得前面几组每组都有m个整数,所以平均值等于各组的和除以m,最后一组就单独加和然后除以对应的数的个数,就可以求出其平均值.

3.细节处理:这里判断n 是否能整除m 是通过比较n/m*m与n的大小,如果相等,则能整除,否则不能整除;因为题意空格要求,最后一个平均值后不能有空格,所以当n能整除m时,先输出前k-1个,每个数后面输出一个空格,最后一个单独输出,不加空格;n不能整除m 时,最后一组单独输出,前面几组输出平均值后紧跟输出空格.这样就能满足题意,使得最后一个平均值后没有多余空格.

4.源代码:

#include

using namespace std;

int main()

{

int b[110];

int n,i,j,m,s,sum,ave,a;

while(cin>>n>>m)

{

a=n/m;

for(i=1;i<=n;i++)

{

b[i]=2*i;

}

if(n-a*m==0)

{

sum=0;

for(i=1;i<=a*m;i++)

{

sum+=b[i];

if(i%m==0)

{

if(i<a*m)

{

cout<<sum/m<<" ";

sum=0;

}

if(i==a*m)

{

cout<<sum/m;

sum=0;

}

}

}

cout<<endl;

}

if(n-a*m!=0)

{

s=0;

sum=0;

for(i=1;i<=a*m;i++)

{

sum+=b[i];

if(i%m==0)

{

cout<<sum/m<<" ";

sum=0;

}

}

for(j=a*m+1;j<=n;j++)

{

s+=b[j];

ave=s/(n-a*m);

cout<<ave<<endl;

}

}

}

return 0;

}

五.母牛与小牛

1.题意:有一头母牛,每年生一小母牛,每头小母牛从四年开始也生一头小母牛,求n年后有多少头牛?

2.解题思路:用到递归,通过找规律我们发现,小母牛第五年才开始生牛,所以第i年的牛是第i-1年的牛和第i-3年的牛的数量总和,所以这是一个递推式,使用for循环我们可以求出第i项,即第i年母牛的数量.

3.细节处理:for循环应从n=4时开始.

4.源代码:

#include

using namespace std;

int main()

{

int cow[60];

cow[1]=1;

cow[2]=2;

cow[3]=3;

for(int

i=4;i<=60;i++)

{

cow[i]=cow[i-1]+cow[i-3];

}

int n;

while(cin>>n)

{if(n==0)

    break;

    else

    {

cout<<cow[n]<<endl;

}}

return 0;

六.到原点距离排序

1.题意:按照绝对值大小排序后输出

2.解题思路:利定义一个数组,用双重循环,一一比较两个数的绝对值大小,如果一个数的绝对值和一个数下标同时大于另一个数,则这两个数交换顺序.

3.细节处理:绝对值函数用fabs,交换函数用swap注意头文件cmath,因为题目要求最后一个数不能再输出空格,所以先单独输入第一个数,然后从第二个数开始先输出空格,再输出数.这样就能保证输出最后一个数没有空格.

4.源代码:

#include

#include

using namespace std

int main()

{

int a[110];

int n,i,j;

while(cin>>n)

{

    if(n==0)

    break;

    if(n!=0)

    {

for(i=1;i<=n;i++)

cin>>a[i];

for(i=1;i<=n;i++)

for(j=1;j<=n;j++)

    {

if(fabs(a[i])>fabs(a[j])&&i>j)

swap(a[i],a[j]);

    }

for(i=1;i<=n;i++)

    {

if(i==1)

cout<<a[i];

if(i>1)

cout<<" "<<a[i];

    }

cout<<endl;

    }

}

}

七.发工资

1.题意:人民币有100元,50元,10元2元,1元六种,求给n个老师发工资至少需要准备的人民币数?

2.解题思路:定义两个数组,第一个数组储存n个老师的工资,第二个数组储存六中不用的人民币数,然后用第一个数组中的每一个数除以第二个数组的每一个数,然后再用这个数除以人民币数求余,最后可以得到人民币的最少张数.

3.细节处理:注意第二个储存人民币的数组要按照面值从大到小储存,这样才能得到最少的人民币数.

4.源代码:

#include

using namespace std;

int main()

{

int

a[110],b[6]={100,50,10,5,2,1};

int

n,sum,i,j;

while(cin>>n)

{

    if(n==0)

    break;

    else

    {

sum=0;

for(i=1;i<=n;i++)

cin>>a[i];

for(i=1;i<=n;i++)

for(j=0;j<6;j++)

        {

sum+=a[i]/b[j];

a[i]=a[i]%b[j];

        }

cout<<sum<<endl;

    }

}

}

八.回文串

1.题意:判断读入的字符是否为回文串(回文串:正读与反读都一样的字符串)

2.解题思路:先读入一个字符串,然后读出这个字符的长度,再利用for循环反向输出这个字符串,然后用循环一一比较这两个字符串是否相等,一旦不相等,就跳出循环,输出no;否则就循环到最后,输出yes.

3.细节处理:读字符串的长度用strlen函数,注意头文件cstring,因为读入一个不加空格的字符,所以可以用scanf读入.

4.源代码:

#include

#include

#include

#include

using namespace std;

int main()

{

char

a[1000],b[1000];

int n,i,j,m;

cin>>m;

while(m--)

{

scanf("%s",a);

n=strlen(a);

for(i=0,j=n-1;i<n;i++,j–)

b[j]=a[i];

    for(i=0;i<n;i++)

    {

if(b[i]!=a[i])

      break;

    }

if(i==n)

cout<<“yes”<<endl;

      else

cout<<“no”<<endl;

}



    return

0;

}

九.进制转换

1.题意:输入一个十进制数N,将它转化为R进制数输出(2<=R<=16,N>=10)

2.解题思路:由于不知道N的正负号,所以我们用if语句进行判断,N=0,直接输出,N<0,令N=-N,用变量进行记录flag=1;N>0,不做处理,用while语句对N进行磨余,每次都令N%R;然后N/=10;用数组储存0所得到的数据,然后逆序输出数组,进行判断如果flag=1,应该先输出一个“-”对数组中的元素进行判断,如果<=9,直接输出,如果大于9,进行强制类型转换,将其转换成字符.

3.细节处理:注意开始对变量初始化,一组输出后应换行。

4.源代码:

#include

#include

#include

using namespace std;

int main()

{

int

arr[1000];

int

r,len,flag;

long long a;

while(cin>>a>>r)

{

    len=0;

    flag=0;

    if(a==0)

    {

cout<<a;

    }

while(a!=0)

    {

if(a<0)

        {

a *= -1;

flag=1;

        }

arr[len++]=a%r;

a/=r;

    }

    for(int

i = len-1;i>=0;i–)

    {

if(flag)

        {

            cout<<"-";

flag=0;

        }

if(arr[i]<=9)

cout<<arr[i];

        else

        {

printf("%c",arr[i]-10+‘A’);

        }

    }

cout<<endl;

}

return 0;

}

十.最后三位数

1.题意:求a^b的最后三位数表示的整数(1<=a,b<=10000)

2.解题思路:因为b的数值可以取到10000,若这时a也很大,那么这个ab数值就会非常大,所以我们不需要输出ab的值,只关注这个数的最后三位数就好.

3.细节处理:只关心这个数的最后三位数,即每次都将这个数除以1000求余,如此循环b次,即可得到这个数的最后三位,而不用具体求出这个数的值.

4.源代码:

#include

#include<math.h>

#include

using namespace std;

int main()

{

long long

int n,a,b;

while(cin>>a>>b)

{

if(a0&&b0)

    break;

    else

    {

    n=1;

    for(int

i=1;i<=b;i++)

n=(n*a)%1000;

cout<<n<<endl;

}

}

return 0;

}

十一.不吉利号码

1.题意:判断一组号码不含有不吉利数字的个数(不吉利数字:所有含有4或62的号码)

2.解题思路:可以先定义一个函数,用来判断一个数是否为不吉利数字,然后在循环中利用函数,判断循环内的数是否为不吉利数,若为不吉利数字,则整形变量加一,最后用总数减去这个记录不吉利数字的变量,便可得到不含有不吉利数字的个数.

3.细节处理:判断是否为不吉利数字的函数可以用bool类型定义,还要注意区间(m,n)中有n-m+1个数.

4.源代码:

#include

bool unlucky(int a)

{

while(a!=0)

{

if(a%104||a%10062)

    {

return true;

    }

    a/=10;

}

return

false;

}

using namespace std;

int main()

{

int

m,n,i,sum,num;

while(cin>>m>>n,m!=0&&n!=0)

{

    num=0;

for(i=m;i<=n;i++)

    {

if(unlucky(i)==true)

num++;

    }

sum=n-m+1-num;

cout<<sum<<endl;

}

return 0;

},

十二.猴子偷桃

1.题意:第一天吃掉总数一半多一个,以后每天吃掉前一天剩下的一半多一个,第n天只剩下一个桃子,求桃子的总数.

2.解题思路:利用逆向思维,从第n天开始模拟,一直到第一天,找出其中的规律,即可求得桃子总数.

3.细节处理:因为第n天剩下1个桃子,所以给桃子总数变量赋初值1,然后利用循环得出第一天到第n-1天的桃子数,与第n天加和得到桃子总数.

4.源代码:

#include

#include

using namespace std;

int main()

{

int n,i,sum;

while(cin>>n)

{

    sum=1;

for(i=0;i<=n-2;i++)

    {

sum+=3*pow(2,i);

    }

cout<<sum<<endl;

}

return 0;

}

十三.夹角大小

1.题意:求平面内两点与原点的连线夹角大小;

2.解题思路:这是一道常见数学题型,求夹角大小可以先求其余弦值,然后利用acos函数(反余弦函数)来求出夹角大小.

3.细节处理:利用acos函数注意头文件cmath,最后还要将弧度制转化为角度制,即乘以180除以圆周率.

4.源代码:

#include

#include

#include

using namespace std;

int main()

{

int n;

double
a,b,c,d,x,y,z,cos;

cin>>n;

cos=0.00;

while(n–)

{

cin>>a>>b>>c>>d;

   x=sqrt((a-c)*(a-c)+(b-d)*(b-d));

y=sqrt(aa+bb);

z=sqrt(cc+dd);

cos=(yy+zz-xx)/(2y*z);

cout<<fixed<<setprecision(2)<<acos(cos)*180/3.1415926<<endl;

   cos=0.00;

}

}

十四.一元二次方程的解

1.题意:输入两个整数a,b,是否能找到两个数x,y,使得x+y=a并且x*y=b;能找到输出yes,不能输出No.

2.解题思路:根据韦达定理,输入的两个输a,b刚好是一元二次方程一次项和常数项的系数,所以根据求根公式可以用数学表达式来表示x^2+ax+b=0的两根。

3.细节处理:需要根据判别式判断方程是否有解,然后还要判断两根是否为整数,可以先定义两个根为实型,然后进行强制转换来判断两根是否为整数.

4.源代码:

#include

#include

#include

using namespace std;

int main()

{

int a,b;

double x,y;

while(cin>>a>>b)

{

if(a0&&b0)

    break;

    else{

    x=0,y=0;

if(aa-4b<0)

cout<<“No”<<endl;

    else

    {

x=(a+sqrt(aa-4b))/2;

y=(a-sqrt(aa-4b))/2;

if(x*100int(x)100&&y100int(y)*100)

cout<<“Yes”<<endl;

        else

cout<<“No”<<endl;

    }

    }

}

}

十五.字符三角形

1.题意:输入一个字符a和一个整数n,输出一个用字符a表示的等腰三角形,高度为n,底边长为2*n-1;(0<n<41)

2.解题思路:可以利用两个for循环,找到字符出现与两个变量的规律,通过两个变量的规律来输出相应的字符

3.细节处理:因为题目要求每个三角形之间空上一行,三角形中间为空,且行末没有多余的空格.所以在输出空格时应注意不能输出三角洲右上角的那部分空格;又因为要每个三角形之间要空上一行,所以第一个三角形不需要空行,到从第二个三角形开始没输入一个字符和一个整数就要输出一行空格,所以每次输入一个字符和一个整数的可以用变量来储存输出的次数,若变量为一,则不做处理,否则要输出一行空格.最后就是如果输入字符@,那么将会跳出循环,可用break语句实现.

4.源代码:

#include

#include

using namespace std;

int main()

{

int n,s;

char a;

s=0;

while(cin>>a)

{

s++;

if(a==’@’)

break;

else

{

cin>>n;

if(s>1)

cout<<endl;

for(int i=1;i<=n;i++)

{

for(int j=1;j<=2*n-1;j++)

{

if(i+jn+1||in||j-i==n-1)

cout<<a;

if(i+j!=n+1&&i<n&&j-i<n-1)

cout<<" ";

}

cout<<endl;

}

}

}

return 0;

}

                                                                  总结

通过这一学期C语言的学习,我内心有很多感慨与感悟:刚开始学C语言的时候,很迷茫,在此之前从没有接触过C语言,有点摸不着头脑。可是在上机过后,我觉得编程是很有趣的一件事。我知道要学好C语言不容易,可是我决定完成这件不容易的事,所以就在吃饭后,睡觉前做那些openjudge的题,刚开始觉得很枯燥无聊,但是通过慢慢的学习,懂得了其中的一些基本用法,就把写代码当成了玩游戏,每次accepted后就很开心,就想打游戏通关了一样,特别有成就感。从而渐渐的自己对C语言的学习也越来越感兴趣。

首先说说我这一学期的C语言学习心得: 我个人觉得,要学好C语言就要先懂得最基本的语法知识,看课本是必需的。我觉得看不懂也没关系,尽力去理解就好了,在对知识有了一个大致的了解过后,就要上机实践。学习C语言一定要动手,只看不做,眼高手低是不行的。最开始可以打书上的例题,熟悉程序,慢慢的开始试着编程。在编程时要理清自己的思路,然后再转换成C语言中的语言,这个时候就更要动手了,只有通过上机操作才能验证自己程序的正确性。执行程序,不要害怕错误,其实,我觉得错误是好的,知道了自己所学知识的不足,并根据提示改正程序中发生的错误,一种成就感油然而生,觉得自己的付出都是值得的?良好的编程习惯是学好C语言的重要因素,只有勤动手,多动脑才能学好C语言,光说不练是不行的。

其次在为期三天的课程设计中,我们整天待在机房,去处理那一个又一个的代码时候,我发现自己对C语言的学习只是学到了其中最为基础的部分,自己的编程能力确实有很大进步的空间,比如一些函数的使用,字符串的处理,以及编程过程的逻辑关系等等都需要自己慢慢去理解,去体会。

自所学的这些知识所能解决的问题非常有限。我在完成这些代码的气候所以说这次课程的设计给我带来了很大的提升,对C语言的了解也变得更加透彻。

最后就是C的用途,刚开始的时候,我还不明白为什么数学专业的学生为什么要学习程序设计,直到后来,我发现其实C语言与数学息息相关,就那我们学的高等代数来说,计算一个高阶行列式用人来算几乎是不可能的,这就需要程序来帮我们实现行列式的计算,记得前几天做C语言题有矩阵的换行换列,以及矩阵的转置,这些都是我们高等代数常见的运算,所以,我深深感受到,今后若想在数学方面有所作为,必须学好编程语言,可以说,数学真的是离不开程序的,尽管C语言这学期就结课了,但是自己在今后的学习中肯定不会放弃C语言的学习,要为今后的数学的计算打下教坚实的基础。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值