zoukankan      html  css  js  c++  java
  • C语言 百炼成钢17

    //题目49:老师将糖果分成若干份,让学生按任意次序领取,第一个领取的,得到1份加上剩余糖果的1/10,
    //第二个领取的,得到2份加上剩余糖果的1/10,第三个领取的,得到3份加上剩余糖果的1/10,以此类推,
    //求共有多少个学生,多少份糖果
    
    #include<stdio.h>
    #include<stdlib.h>
    
    //思路:该题的要求是求一个糖果的数量,这个数量必须保证每个学生领取到的糖果都是整份数,并不要求所有学生分的糖果分数一样
    //根据多定义变量,简化运算难度规则,定义有x个学生,y份糖果
    //通过列举,找出规律:
    //1+(y-1)*(1/10)  第一个学生领取的糖果数量
    //抽象函数
    //f(1)=1+(y-1)*(1/10) 
    //因为每个学生领取到的糖果都是整份数,所以(y-1)*(1/10) 是整数,说明y-1是10的倍数
    //那么y=10n+1
    //通过枚举可以得到y的数量
    //定义一个变量last,来存储糖果的剩余量,一直到last=0为止
    //第一次 last=y-第一个学生领取的糖果数量,即last=y-1-(y-1)*(1/10) ---在枚举过程中y是个已知量
    //第二次 last=last-第二个学生领取的糖果数量,即last=last-(2+(last-2)*(1/10))
    //此时需要保证 last-2是10的倍数,即(last-2)%10==0,不满足这个条件,苹果的数量就要发生变化
    //y=10n+1将n++
    //还需要last>0
    //当last==0时,获得正常的学生数量和糖果数量
    //当last<0时,说明糖果数量不正常,需要将n++ ,再次循环
    //第三次 lats=last-第三个学生领取的糖果数量,即last=last-(3+(last-3)*(1/10))
    
    //不确定循环次数,使用while循环
    
    
    
    
    void main(){
        //定义自增变量
        int n = 1;
        //定义每次糖果剩余数量
        int last = 10 * n + 1;
        //定义学生人数
        int index = 1;
        while (1){
            //一次都没有循环时,剩余糖果数量等于总糖果数量
            //开始循环
            //开始第一次
            //剩余苹果的数量必须是10的倍数
            if ((last - index)%10!=0)
            {
                //说明本次的糖果总数量不满足所有条件
                n++;
                //初始化所有数据
                last = 10 * n + 1;
                index = 1;
                //进行下一次循环
                continue;
            }
            last = last - (index + (last - index)/10);
            if (last == 0)
            {
                //说明本次的糖果总数量满足所有条件
                break;
            }
            else if (last>0)
            {
                index++;
            }
            else{
                //说明本次的糖果总数量不满足所有条件
                n++;
                //初始化所有数据
                last = 10 * n + 1;
                index = 1;
                //进行下一次循环
                continue;
            }
            if (n>100)
            {
                printf("看来我写的代码已经出错了!
    ");
                break;
            }
            
        }
        if (index!=1)
        {
            printf("一共有%d个学生,糖果一共有%d份
    ", index, 10 * n + 1);
        }
        system("pause");
    }

    //题目50:幼儿园给学生从前向后发糖果,每个学生得到的糖果成等差数列,前四个学生得到糖果的和是26,积是880,
    //求前20名学生各自的糖果数目
    
    
    #include<stdio.h>
    #include<stdlib.h>
    
    //思路:求出前20个学生的糖果,必须知道一个学生的糖果和等差的差
    //a1+a2+a3+a4=26,因为a2=a1+d,a3=a1+(3-1)d;即4a1+d+2d+3d=26;=>4a1+6d=26
    //a1*a2*a3*a4=880;a1*(a1+d)*(a1+2d)*(a1+3d)=880
    //糖果是个正整数,所以4a1+6d=26(即2a1+3d=13),a1和d全是整数,所以a的范围是0<a1<7;0<d<5
    //因此使用双循环
    
    void main(){
        int a[20] = { 0 };
        int d = 0;
        for (int i = 1; i < 5; i++)
        {
            for (int j = 1; j < 7; j++)
            {
                if (2*j + 3*i == 13)
                {
                    if (j*(j + i)*(j + 2*i)*(j + 3*i) == 880)
                    {
                        a[0] = j;
                        d = i;
                        break;
                    }
                    continue;
                }
            }
        }
        for (int i = 0; i < 20; i++)
        {
            if (i==0)
            {
                printf("%5d", a[i]);
            }
            else{
                a[i] = a[0] + i*d;
                printf("%5d", a[i]);
            }
        }
        system("pause");
    }
    
    
    //总结:本题是练习是解决二元方程的编程解法,二元方程编程的关键是确定两个元的范围,用穷举法求出结果,
    //好的编程在于缩小两个元的范围,本题元的范围可以更小,2a1+3d=13,a1=6其实也不符合条件,因为此时3d=1,d不可能是整数

    //题目51:两个不同的自然数A和B,如果整数A的全部因子(包括1,不包括A本身)之和等于B;
    //且整数B的全部因子(包括1,不包括B本身)之和等于A,则将整数A和B称为亲密数.求10000以内的全部亲密数.
    
    #include<stdio.h>
    #include<stdlib.h>
    #include<math.h>
    
    //思路:本题先求一个数A的所有因子,再将因子之和求出来,得到数B,判断数B的范围在不在10000之内,
    //在求出B的因子之和是否等于A
    //求出一个数所有因子 先求出数A的平方根,再用循环的方法求出所有的因子
    
    int run1(int num){
        int a = (int)sqrt((double)num)+1;
        int sum = 1;
        for (int i = 2; i < a; i++)
        {
            if (num%i==0)
            {
                sum = sum + i + num / i;
                //sum += i;
            }
        }
        return sum;
    }
    
    
    void main(){
        int a[100] = { 0 };
        int index = 0;
        int temp = 0;
        for (int i = 4; i < 10000; i++)
        {
            //获取数A的因子之和
            temp = run1(i);
            //判断数B的范围
            //要求大于A,并且在10000以内,并且数A不等于数B
            if (temp<i||temp>10000||(temp==i))
            {
                continue;
            }
            //求出数B的因子之和
            if (i == run1(temp))
            {
                printf("%d==>%d
    ",i,temp);
            }
        }
        system("pause");
    }
    
    //总结:本题难点在于求出数A的因子,关键在于缩小A因子的范围(int)sqrt((double)num)+1

  • 相关阅读:
    HttpWebRequest 的一个 异步封装
    AcWing 6 多重背包问题III【单调对列优化】
    AcWing 8. 二维费用的背包问题
    AcWing 1019. 庆功会
    P1421 小玉买文具
    P5709 【深基2.习6】Apples Prologue / 苹果和虫子
    P2181 对角线
    AcWing 1020. 潜水员
    AcWing 1013. 机器分配【分组背包+求方案数】
    AcWing 7. 混合背包问题
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/5201685.html
Copyright © 2011-2022 走看看