ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C语言程序设计100例之(46):巧妙称重

2022-01-13 07:00:06  阅读:202  来源: 互联网

标签:46 样例 C语言 金币 int 袋子 printf 100 钱袋


例46  巧妙称重

题目描述

有N个篮子,编号1~N,篮子中有很多金币,每个重w。但是有一个编号的篮子中,每个金币重d。现从第一个篮子中拿1个金币,第二个篮子中拿2个,…,第N-1中拿N-1个,第N中不拿,给出这些金币的总重量wei,问:是第几个篮子中的金币重量较轻?

输入格式

输入文件将由一行或多行组成;每行包含四个正整数,由一个空格分隔。前三个整数分别是数字N、w和d,如上所述。第四个整数是所选硬币称重的结果。

N至少为2,但不超过8000。w的值最多为30。d的值将小于w。

输出格式

对于每组测试数据输出一行,由一个正整数组成:装有比其他篮子中金币轻的金币的篮子编号。

输入样例

10 25 8 1109

10 25 8 1045

8000 30 12 959879400

输出样例

2

10

50

        (1)编程思路。

        这是一道数学题分析题。若设1~N-1这N-1个篮子中放的金币均为重量为w的金币,则应有的总重量为:w*(1+n-1)*(n-1)/2(简单的等差数列求和),所求的和减去实际称出的重量wei,得到金币重量的差值sum = ((n-1)*(n-1+1)/2)*w-wei。若sum为0,则装有重量为d的篮子编号必为N;若sum不为0,除以d,得到较轻金币的个数,即为所求编号。

(2)源程序。

#include <stdio.h>

int main()

{

     int n,w,d,p;

     while (scanf("%d%d%d%d",&n,&w,&d,&p)!=EOF)

     {

         int sum = ((n-1)*(n-1+1)/2)*w-p;

         if(sum==0)

             printf("%d\n",n);

         else

             printf("%d\n",sum/d);

     }

     return 0;

}

习题46

46-1  鬼谷子的钱袋

        本题选自洛谷题库 (https://www.luogu.org/problem/P2320)

题目描述

鬼谷子非常聪明,正因为这样,他非常繁忙,经常有各诸侯车的特派员前来向他咨询时政。

有一天,他在咸阳游历的时候,朋友告诉他在咸阳最大的拍卖行(聚宝商行)将要举行一场拍卖会,其中有一件宝物引起了他极大的兴趣,那就是无字天书。

但是,他的行程安排得很满,他已经买好了去邯郸的长途马车票,不巧的是出发时间是在拍卖会快要结束的时候。于是,他决定事先做好准备,将自己的金币数好并用一个个的小钱袋装好,以便在他现有金币的支付能力下,任何数目的金币他都能用这些封闭好的小钱的组合来付账。

鬼谷子也是一个非常节俭的人,他想方设法使自己在满足上述要求的前提下,所用的钱袋数最少,并且没有两个钱袋装有相同的大于1的金币数。假设他有m个金币,你能猜到他会用多少个钱袋,并且每个钱袋装多少个金币吗?

输入格式

包含一个整数,表示鬼谷子现有的总的金币数目m。其中,1≤m ≤1000000000。

输出格式

两行,第一行一个整数h,表示所用钱袋个数

第二行表示每个钱袋所装的金币个数,由小到大输出,空格隔开

输入样例

3

输出样例

2

1 2

       (1)编程思路。

先看看金币数目m为1~10怎么表示。

m=1,显然1个钱袋,装1个金币;m=2,用2个钱袋,各装1个金币;

m=3,用2个钱袋,分别装1个和2个金币;

m=4,用3个钱袋,分别装1个、1个和2个金币;

m=5,用3个钱袋,分别装1个、1个和3个金币;

m=6,用3个钱袋,分别装1个、2个和3个金币;

m=7,用3个钱袋,分别装1个、2个和4个金币;

m=8,用4个钱袋,分别装1个、1个、2个和4个金币;

m=9,用4个钱袋,分别装1个、1个、2个和5个金币;

m=10,用4个钱袋,分别装1个、1个、3个和5个金币;

……

        由上面规律可以看出,n以内的任何数字可以用1到n/2以内的数字表示,n/2以内的任何数字可以用1到n/4以内的数字表示,……。

        例如,为了表示15,一个袋子装(15+1)/2=8个金币,剩下7个金币;为了表示7,用一个袋子装(7+1)/2=4个金币,剩下3个金币;为了表示3,用一个袋子装(3+1)/2=2个金币,剩下2个金币,可用两个袋子,各装1个金币。即m=15,用4个钱袋,分别装1个、2个、4个金币和8个金币;

        M=29时,一个袋子装(29+1)/2=15个金币,剩下14个金币用4个袋子,分别装1个、2个、4个金币和7个金币。

        M=30时,一个袋子装(30+1)/2=15个金币,剩下15个金币用4个袋子,分别装1个、2个、4个金币和8个金币。

        M=31时,一个袋子装(31+1)/2=16个金币,剩下15个金币用4个袋子,分别装1个、2个、4个金币和8个金币。

        ……

       (2)源程序。

#include <stdio.h>

int main()

{

    int a[32];

    int n;

    scanf("%d",&n);

    int cnt=0;

    while (n>0)

    {

        a[cnt++]=(n+1)/2;

        n=n/2;

    }

    printf("%d\n",cnt);

    for (int i=cnt-1;i>=0;i--)

        printf("%d ",a[i]);

    printf("\n");

    return 0;

}

46-2  圆桌会议

题目描述

N个哲学家围坐在一张圆形的桌子旁进行交流。在一天在讨论的时候,哲学家Eddy想出了一个极为古怪的想法,如果他们在每一分钟内,一对相邻的两个哲学家交换一下位子,那么要多少时间才能得到与原始状态相反的座位顺序呢?

输入格式

对于给定数目N(1<=N<=32767),表示有N个哲学家,求要多少时间才能得到与原始状态相反的座位顺序,即对于每个人,原先在他左边的人后来在他右边,原先在他右边的人在他左边。

输出格式

对每个数据输出一行,表示需要的时间(以分钟为单位)。

输入样例

4

5

6

输出样例

2

4

6

       (1)编程思路。

        若n个哲学家坐成一排,123…n逆序变为n…321,需要交换位置1+2+…+(n-1)=n*(n-1)/2次,即1右移n-1步,2右移n-2步,……。

       现在n个哲学家在圆桌边围成一圈,所以可以双向移动,因而可将n分成两部分,n/2和n-n/2,两部分分别按一排独自逆序,可以达到时间最少。

       例如1234,可分成12和34,2分钟后可得到2143,由于成圈,所以也是逆序。

       再如12345,可分成123和45,123逆序为321用2分钟,45逆序为54用1分钟,3分钟后可得到32154,由于成圈,所以也是逆序。

      (2)源程序。

#include <stdio.h>

int main()

{

    int n;

    while(scanf("%d",&n)!=EOF)

    {

        int a=n/2;

        int b=n-a;

        printf("%d\n",a*(a-1)/2+b*(b-1)/2);

    }

    return 0;

}

46-3  取木棍

题目描述

有边长分别为1~n的n根小木棍,现在要求拿走尽量少的小木棍,使得剩下的小木棍任意取三根都不能组成三角形。

输入格式

输入第一行包含一个整数T(T≤20),表示测试用例的数量。

对于每个测试用例,只有一行描述给定的整数n(1≤N≤20)。

输出格式

对于每个测试用例,输出一行“case#x:y”,其中x是用例编号(从1开始),y是应取走的最小木棍数目。

输入样例

3

4

5

6

输出样例

Case #1: 1

Case #2: 1

Case #3: 2

        (1)编程思路。

        边长为1~n的n根小木棍取走一些后,若最后剩下的小木棍的边长构成Fib(斐波那契)数列,则一定可以保证任意三根木棍都不能组成三角形。

      (2)源程序。

#include <stdio.h>

int main()

{

    int a[22]={0};

    a[1]=a[2]=a[3]=a[5]=a[8]=a[13]=a[21]=1;

    int i;

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

        a[i]+=a[i-1];

    int t;

    scanf("%d",&t);

    for (i=1; i<=t; i++){

        int n;

        scanf("%d",&n);

        printf("Case #%d: %d\n", i,n-a[n]);

    }

    return 0;

}

标签:46,样例,C语言,金币,int,袋子,printf,100,钱袋
来源: https://www.cnblogs.com/cs-whut/p/15796126.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有