noj循环(11~20)详解

011你会存钱吗

循环的层层套用,(多少有点硬凑的感觉,对超过存款期限的那一部分时间不付利息,所以固定的年限也可以被拆开了)

简单说说思路:利用c1c2c3c4c5来确定每个存款年限存的次数,然后将收益放入sum中,每一次方案的变化,都执行一次sum与max的比较,使a1a2a3a4a5记录下当前最大的收益的存款方案,循环结束后,a1a2a3a4a5就记录下了最大存款方案,max就存放着最大收益。

这里为了方便计算利用了pow函数,pow(a,n)是计算a的n次方,该函数也是在math.h库里的(简单说明)。

代码如下:

#include<stdio.h>
#include<math.h>
int main ()
{
    int a8,a5,a3,a2,a1,c8,c5,c3,c2,c1;
    double max=2000;
    double r1=0.0063,r2=0.0066,r3=0.0069,r5=0.0075,r8=0.0084;
    for (int c8=0;c8<=2;c8++)
       for (int c5=0;c5<=(20-c8*8)/5;c5++)
           for (int c3=0;c3<=(20-c8*8-c5*5)/3;c3++)
               for (int c2=0;c2<=(20-c8*8-c5*5-c3*3)/2;c2++)
                {
                    int c1=20-c8*8-c5*5-c3*3-c2*2;
                    double sum;
                    sum=2000*pow(96*r8+1, c8)*pow(60*r5+1, c5)*pow(36*r3+1, c3)*pow(24*r2+1, c2)*pow(12*r1+1, c1);
                    if (max<sum)
                    {
                        max=sum,a1=c1,a2=c2,a3=c3,a5=c5,a8=c8;
                    }
                }
    printf ("%d %d %d %d %d\n",a8,a5,a3,a2,a1);
    printf ("%.2f",max);
    return 0;
}

012VOL大学乒乓球比赛

(这个题感觉很奇怪,我怀疑只放printf语句也可以通过,感觉写程序与不写程序区别不大,直接放我通过的代码吧...)

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int A=1,B=2,C=3,X,Y,Z;
    for(Y=1;Y<=3;Y++)
    {
        for(Z=1;Z<=3;Z++)
        {
            for(X=1;X<=3;X++)
            {
                if(X!=A&&X!=C) break;
            }
            if(Z!=X&&Z!=C) break;
        }
        if(Y!=X&&Y!=Z) break;
    }
    if(A==X)printf("A=X\n");
    if(A==Y)printf("A=Y\n");
    if(A==Z)printf("A=Z\n");
    if(B==X)printf("B=X\n");
    if(B==Y)printf("B=Y\n");
    if(B==Z)printf("B=Z\n");
    if(C==X)printf("C=X\n");
    if(C==Y)printf("C=Y\n");
    if(C==Z)printf("C=Z\n");
    return 0;
}

013二分求根

二分法,首先要有初中数学知识~,取区间的中间值,然后带入多项式,如果多项式小于0或者大于0,那么再取另一部分区间的中间值,一直到所取中间值是方程的解;

那么如何利用循环来实现?为了方便,我还是写了一个函数,用来返回多项式的“值”,如果大于0返回1,小于0返回-1,等于0就返回0;这样只需要对返回值进行分支语句判断,就可以确定下一次取中间值得区间;

那么循环条件自然而然就可以是函数返回值,只要函数返回值为0,循环就结束。

代码如下:

#include <stdio.h>
#include <stdlib.h>

float f(float x)
{
    float r = 2*x*x*x-4*x*x+3*x-6;
    if(r>0)return 1;
    if(r<0)return -1;
    return 0;
}

int main()
{
    float x1,x2;
    scanf("%f%f",&x1,&x2);
    float x = (x1+x2)/2;
    while(f(x))
    {
        if(f(x)==1)
        {
            x2 = x;
            x = (x1+x2)/2;
        }
        else if(f(x)==-1)
        {
            x1 = x;
            x = (x1+x2)/2;
        }
    }
    printf("%.2f",x);
    return 0;
}

014奇特的分数数列

这道题观察规律写出代码还是比较容易的,我们发现这个数列,下一项的分子,是前一项的分子+分母,下一项的分母,是前一项的分子;循环次数为20,每次记录总和就好了。

但是我写代码的时候出现了小问题(现在我其实还不是很明白,只能迷迷糊糊的认为是精度问题),定义变量用float和double得出的结果是不同的,double得出的就是正确输出,而float得出的输出是32.660263,对于这一点,我只能归结为double双精度更精确,所以中间步骤中,没有“吞掉数”;

代码如下:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    double sum=0,fz=2,fm=1,tem;
    for(int i=1;i<=20;i++)  //控制循环次数为20次
    {
        sum = sum + fz/fm;
        tem = fz;
        fz = fz+fm;
        fm = tem;
    }
    printf("%lf",sum);
    return 0;
}

015两个整数之间所有的素数

这个题主要是如何判断是否是素数(质数);(如果做一下2022年数学新高考一卷,那么你一定很明白质数是什么)另一个小注意点是,输入的整数需要自行调整大小顺序;

调整顺序其实就是比较大小,然后进行互换赋值,三个变量就可以搞定了。

素数的概念是,除了1和本身,没有其他整数可以使它被整除。自然而然想到循环取余,判断是否为零。

所以还是写了一个函数来简化代码;

代码如下:

#include <stdio.h>
#include <stdlib.h>

int prime_number(int x)  //素数返回1;非素数返回0
{
    int i;
    if(x==2) return 1;           //2是素数
    for(i=2;i<x;i++)
    {
        if(x%i==0) return 0;  //能被其他数整除是非素数
    }
    return 1;       //不能被其他数整除是素数
}

int main()
{
    int a,b,c;
    scanf("%d%d",&a,&b);
    if(a>b) c=a,a=b,b=c; //执行后a<b
    for(int i=a;i<=b;i++)
    {
        if(prime_number(i)) //素数返回1,if语句执行,实现打印;
        {
            printf("%d ",i);
        }
    }
    return 0;
}

016 五猴分桃

这道题有枚举的意思,就是一个个数去尝试,直到求出满足条件的最小数。

我们让i是循环变量,每次递增;然后x是猴子的个数,x控制循环5次,对i执行i%5是否为1(根据条件得,总数平均分为五份后,每次都多出一个),如果是1,则i变为取走后的四份桃子,循环继续;如果不是1,那么直接跳出循环。(这里要注意的一点是,i是外层循环变量,所以一切操作不能对i进行,不然循环会变为死循环,最好的方法就是将i的值记录下来,对记录的那个数进行操作)

代码如下:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int sum,i,tao;
    for(sum=1000;;sum++)
    {
        tao=sum;
        for(i=1;i<=5;i++)
        {
            if(tao%5==1)
            {
                tao=4*(tao-1)/5;
            }
            else break;
        }
        if(i==6)
        {
            printf("%d %d",sum,tao);
            break;
        }
    }
    return 0;
}

017 完全数

这个题和015很类似,只不过一个是判断是否为素数,这个是判断因子之和是否等于原数,麻烦的地方可能是按格式输出,这里还没进行到数组所以我用了两次循环去实现判断加输出。

代码如下:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int sum=0;
    for(int i=2;i<=1000;i++)    //遍历2-1000;
    {
        for(int x=1;x<i;x++)      //记录因子之和
        {
            if(i%x==0) sum=sum+x;
        }
        if(sum==i)               //判断是否为完全数,是则执行后续代码
        {
            printf("%d=1",i);        //每个数因子一定有1
            for(int x=2;x<i;x++)
            {
                if(i%x==0) printf("+%d",x);  //按格式打印
            }
            printf("\n");         //实现换行
        }
        sum = 0;              //sum归零重新记录
    }
    return 0;
}

018 计算π

这个题感觉有点问题,感觉给的答案是错误的。

从题干看,直到括号中最后一项(记为y)的绝对值小于0.000001为止,那么括号里最后一项,就是y而且y是包含在结果里的;但是根据这个写出来的代码答案与所给答案不一致(并不是博主写错了,检查了好几遍),而如果再加上y的后一项,或者把y的操作还原,答案就与所给答案一致了..

这个循环也不是很难,奇数项是加,偶数项是减,分母是2*x-1;很容易可以写出来,控制循环的条件变为项的大小就可以了。

代码如下:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    double pi=0,i=1;
    int x;
    for(x=1;i>=0.000001;x++)
    {
        i = 1.0/(2*x-1);
        if(x%2==1)    //奇数项相加
        {
            pi = pi+i;
        }
        else         //偶数项相减
        {
            pi = pi-i;
        }
    }
    if(x%2==1)    //x是奇数把最后一项i加回去
    {
        pi = pi+i;
    }
    else         //x是偶数把最后一项i减回去
    {
        pi = pi-i;
    }
    printf("%lf",4*pi);
    return 0;
}

019 最次方数

这个题初次做挺容易错的..他牵扯数据溢出的问题,就是你13的13次方,太大了,然后导致你的数据溢出,从而导致最后结果不正确。

因为我们只需要最后三位数结果,所以高位数的乘法也好,进位也好,对于低位数来说是不受影响的,所以我们每次运算之后,都对结果进行取余(%1000),提取低三位,这样既可以保证数据不会溢出,也可以求出最后三位数的结果。

代码如下:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int x,a,n;
    scanf("%d%d",&x,&a);
    n = x;
    for(int i=1;i<a;i++)     //控制循环次数为a-1次(13个x相乘,执行12次)
    {
        n = n*x;
        n = n%1000;
    }
    printf("%d",n);
    return 0;
}

020 区间内素数

(发现这组题里好多关于素数问题的,套用起来也挺方便,思路都是同样的..)

(前面没有解释)这里简单解释一下自己写的函数int prime_number(int x)第一个int是指我的函数的返回值类型是整数型(通俗说就是return 后面的数是整数)然后prime_number是我起的名字(秉承着函数名要与函数功能一致,所以函数名翻译过来就是质数的意思),括号内的(int x)是指参数,就是传递给我这个函数的参数是一个整数,函数内容呢就是对传过来的参数进行判断,是素数就返回1,不是素数就返回0;

设计思路就是根据返回值,决定是否执行,cnt++以及sum的操作;

代码如下:

#include <stdio.h>
#include <stdlib.h>

int prime_number(int x)  //素数返回1;非素数返回0
{
    int i;
    for(i=2;i<x;i++)
    {
        if(x%i==0) return 0;  //能被其他数整除是非素数
    }
    return 1;       //不能被其他数整除是素数
}

int main()
{
    int cnt=0,sum=0;
    for(int i=800;i>=500;i--)   //题目中由大到小排序
    {
        if(prime_number(i))
        {
            cnt++;          //是素数,所以次数自增
            if(cnt%2==1) //cnt为奇数所以相加
            {
                sum = sum + i;
            }
            else
            {
                sum = sum - i;
            }
        }
    }
    printf("%d %d",cnt,sum);
    return 0;
}

新手上路,编写不易,欢迎指正,多多支持~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值