幻想森林

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 4283|回复: 10

[通用编程] C程序题

[复制链接]

313

主题

1574

帖子

1万

积分

⑧专业

*永恒国度*

积分
14145
QQ
发表于 2007-10-6 23:45:38 | 显示全部楼层 |阅读模式
新年晚会老师给大家分糖,手端着一盘糖,让第一个同学先拿1块糖,再把盘中的糖分1/7给他;然后让第二个同学拿2块糖,再把盘中的糖的1/7给他;第三个同学拿3块糖后,仍把盘中的糖的1/7给他。照这个办法分下去,最后一个同学自己拿完糖后,糖恰好分完,而且每个人分到的糖块数相同。问共有几人?每人分几块糖?

由“最后一个同学自己拿完糖后,糖恰好分完”以及前面的条件可知,最后一个同学所拿的糖的数量刚好等于人数。

这个题应该怎么编写呢?
[img][/img] http://shop33698673.taobao.com被别人嫉妒,证明你优秀,嫉妒别人说明你无能
回复

使用道具 举报

313

主题

1574

帖子

1万

积分

⑧专业

*永恒国度*

积分
14145
QQ
 楼主| 发表于 2007-10-7 02:16:33 | 显示全部楼层
main()
      {int t=0,m,n,i,j;
      for (m=6;!t;m+=6)        --------> 这里M为什么以6开始???
      {t=1;n=m;                    /*n为最后一个同学所拿到的糖的数量(即
                  人数),t=1假设当前n满足条件*/
      for (i=m-1;(i>=1)&&t;i--)
        {j=n/6+i;                /*第i个同学分到的糖的数量*/------>为什么这里等于第I个的数量呢?
      n=n/6*7+i;              /*第i个同学分到糖之前所剩的糖的数量*/
      if (j!=m) t=0;          /*每个人分到的糖块数相同.不满足就退
                  出模拟过程对人数重新取值*/
          }
    }
   printf ("%6d%6d\\n",m-6,m-6);
}
看到这样的解答 实在是不太看得懂
[img][/img] http://shop33698673.taobao.com被别人嫉妒,证明你优秀,嫉妒别人说明你无能
回复 支持 反对

使用道具 举报

8

主题

215

帖子

2223

积分

⑥精研

积分
2223
发表于 2007-10-7 03:16:39 | 显示全部楼层
我觉得...这题既然是让计算机算的,能不动人脑就不动人脑 (被拖走
好吧,不开玩笑,不过这题有十分多的高效解法.不可能全列出来.复杂的也不列出来,只说最直观的.

其中最短的就是纸笔推出数列通项,求和列一个一元方程.这个就算了.直接把答案输出出来就行 (死

再次,可以依靠"最后一个同学所拿的糖的数量刚好等于人数"+"每个人分到的糖块数相同"+"第n个人要先拿n块糖"来入手.这几个条件综合得知,假如总共有n人,那么最后一个同学(也就是第n个同学)要拿n块糖,同时糖已分完.进一步知道,每个同学拿到的糖数都是n块.所以糖的总数是n的平方.然后再把第一个同学所拿的糖拿来列一个一元二次方程...喂喂这不又直接求出答案了么.

所以,我们换种"蠢"一点的做法来玩玩.在分析得知糖的总数是人数的平方之后,我们就穷举所有大于1的正整数的平方作为糖数,按照最直观的方式去把糖"分配"下去,看看糖分到最后是否能正好分完.如下:
  1. #include <stdio.h>
  2. #define TRUE 1
  3. #define FALSE 0
  4. #define DIVISOR 7
  5. typedef int bool;
  6. bool dist( int ord, int remain ) {
  7.     if ( remain == ord )
  8.         return TRUE; /* 正确分完 */
  9.     if ( remain < ord || remain % DIVISOR != ord )
  10.         return FALSE; /* 不满足分配条件 */
  11.    
  12.     return dist( ord + 1, remain - ord - ( remain - ord ) / DIVISOR );
  13. }
  14. void main(void) {
  15.     int person = 2;
  16.     while ( dist( 1, person * person ) == FALSE )
  17.         person++;
  18.     printf( "%d", person );
  19. }
复制代码
其它的玩法还有很多...例如说可以完全无视上面的分析,硬把大于1的自然数穷举一遍,作为糖数扔进上面那递归函数去分析也可以,收敛速度会慢很多但这数字本来就小,看不出来的. = =
不用平方也不穷举,还可以通过第一个同学拿糖的情况,知道糖总数N肯定符合N = 7k + 1,其中k=1,2,3,4,...用这个条件扔进去检测也可以.
我上面的检测方法是直观的,正向的检查.反过来从最后一个同学开始检查也可以.
用递归也可以,用循环也可以.
总之办法多的是.

P.S. 其实按道理说只有1人,每人拿到1糖的结果也符合规律,只不过题目里已经出现了3,就假设人数大于等于3吧.这样在解一元二次方程的时候也可以扔掉一个解.

Have fun ^ ^
回复 支持 反对

使用道具 举报

8

主题

215

帖子

2223

积分

⑥精研

积分
2223
发表于 2007-10-7 03:46:27 | 显示全部楼层
LZ的代码一如既往难以阅读...
  1. #include <stdio.h>
  2. #define TRUE 1
  3. #define FALSE 0
  4. typedef int bool;
  5. void main( void ) {
  6.     int m, n, i, j;
  7.     bool done = FALSE;
  8.    
  9.     for ( m = 6; !done; m += 6 ) { /* --------> 这里m为什么以6开始??? */
  10.         done = TRUE;
  11.         n = m;                    /* n为最后一个同学所拿到的糖的数量(即人数),done=TRUE假设当前n满足条件 */
  12.         for ( i = m - 1; ( i >= 1 ) && done; i-- ) {
  13.             j = n/6 + i;                /* 第i个同学分到的糖的数量 ------>为什么这里等于第i个的数量呢? */
  14.             n = n/6*7 + i;              /* 第i个同学分到糖之前所剩的糖的数量*/
  15.             if ( j != m )
  16.                 done = FALSE;          /* 每个人分到的糖块数相同.不满足就退出模拟过程对人数重新取值 */
  17.         }
  18.     }
  19.     printf ("%6d%6d\\n", m-6, m-6);
  20. }
复制代码
建议LZ以后写好代码发出来之前先用astyle把代码格式化一次...

好吧LZ你要是是在书上看到这种解法的话,发email问它作者那m的意义你就明白了.是谁告诉你的就问谁吧,这代码 =_=||
回复 支持 反对

使用道具 举报

313

主题

1574

帖子

1万

积分

⑧专业

*永恒国度*

积分
14145
QQ
 楼主| 发表于 2007-10-7 10:22:22 | 显示全部楼层
astyle是什么东东? [s:5]
[img][/img] http://shop33698673.taobao.com被别人嫉妒,证明你优秀,嫉妒别人说明你无能
回复 支持 反对

使用道具 举报

8

主题

215

帖子

2223

积分

⑥精研

积分
2223
发表于 2007-10-7 10:39:16 | 显示全部楼层
没用过astyle也不知道是什么的话,请善用搜索引擎
http://astyle.sourceforge.net/
是一个美化/格式化代码的小工具.开源,免费.
回复 支持 反对

使用道具 举报

50

主题

742

帖子

402

积分

版主

自定义头衔

Rank: 7Rank: 7Rank: 7

积分
402
发表于 2007-10-7 13:19:02 | 显示全部楼层
代码整理VC内置的巴?
ASTYLE是什么………………
Style-C
回复 支持 反对

使用道具 举报

19

主题

842

帖子

1万

积分

⑧专业

絕望青年,一起增高吧

积分
13676
发表于 2007-10-7 16:27:41 | 显示全部楼层
某在eclipse已經解決格式的問題...用astyle的是vim達人吧
LZ的編程習慣還是有待改善...如果是某的同學,某C會好好調教的說...

這題如red君所言,還是先有數學式表達才真正編程
始終編程只是工具,沒有數學和邏輯編程是沒有意義的

為著彼岸,便要與之妥協 但為著彼岸,更不能與之妥協

回复 支持 反对

使用道具 举报

8

主题

215

帖子

2223

积分

⑥精研

积分
2223
发表于 2007-10-7 18:57:52 | 显示全部楼层
因为Eclipse的CDT在我自己上跑实在太慢,3.1和3.1.2之后我就再也没在Eclipse里用过CDT了.
JDT的话我确实是非常喜欢用Eclipse.代码格式化/重构/自动完成的功能相当不错.

推荐Astyle是因为不想假设别人用了什么IDE或者编辑器,所以推荐脱离IDE也能单独使用的格式化小工具嘛
回复 支持 反对

使用道具 举报

11

主题

17

帖子

1331

积分

⑥精研

积分
1331
发表于 2007-10-14 05:42:56 | 显示全部楼层
引用第1楼august于2007-10-07 02:16发表的  :
  main()
      {int t=0,m,n,i,j;
      for (m=6;!t;m+=6)        --------> 这里M为什么以6开始???
      {t=1;n=m;                    /*n为最后一个同学所拿到的糖的数量(即
                  人数),t=1假设当前n满足条件*/
.......
就是问为什么以6开始?这个简单啊...因为还剩余 6份啊 6/7嘛!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|幻想森林

GMT+8, 2024-5-3 09:15 , Processed in 0.028458 second(s), 21 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表