回 帖 发 新 帖 刷新版面

主题:第37次编程比赛第1题结果

测试环境:winxp+vc6, re楼ease版本,AthLonXP2000+/768MB

第一轮 2<=n<30

3楼 euc:Wrong Answer
5楼 ITER:Wrong Answer
6楼 hyerty:Wrong Answer
7楼 Liangbch:AC 
8楼 ccpp:Wrong Answer  接口小问题,帮你改好。但结果还是……
9楼 xyhx:AC 
12楼 Liyanguestc:Wrong Answer   接口不对 只好把你的单独运行,下次留意格式。
13楼 太没劲了:Wrong Answer
14楼 hyerty:Wrong Answer
17楼 joekings:Wrong Answer
18楼 joekings:Wrong Answer
20楼 boxertony:Wrong Answer
21楼 jackin0627:Wrong Answer
22楼 xyhx:不知道为什么,运行起来是死循环,可能是我的问题,你告诉我怎么改。不过你在9楼交的很不错。


第二轮:
7楼 Liangbch:n=100 1s;n=150 23s; 不敢再测更大的。
9楼 xyhx:受限int类型,n>100结果错误。n<100速度稍逊Liangbch。



总的说明:
    从提交人数和正确率来看,这道题看起来还是有一定难度。严格的说没有人完全通过,在100以内仅有2人是正确的。有两个值错误率比较高:n=20(5+7+8) maxStep=5*7*8=280; n=21(2+3+4+5+7) maxStep=3*4*5*7=420。
    xyhx很可惜没有用到int64或者longlong。Liyanguestc作为新人还是很不错,n>100时结果正确,n=150仅需2s,可惜数据类型很投机的使用了double,n>150之后结果错误,并且n=18结果也是错误,说明算法有小问题。Liangbch的结果正确,速度不算慢,孩子生病还来捧场,太感谢了。

    这道题其实可以具体到一句话:将n分解成若干个大于1的自然数的和,使它们的最小公倍数最大。暂时没有更好的方法,只能是搜索+剪枝。剪枝策略就是尽量互质,分解成若干个质数或者质数的幂,使它们的和小于等于n(但不等于n-1,n-1特殊考虑)。剪枝充分的话,速度完全可以达到题目的要求,而且代码只需四五十行。

    作为唯一一个结果正确的人,本次比赛的[color=FF0000]冠军为Liangbch[/color]。xyhx的结果int范围也是正确的,获得优胜奖。

    Liyanguestc作为新人,表现出了非常大的潜力,剪枝做的非常好,速度很快。但可惜算法有一点漏洞,结果不是完全正确。期待下次的表现。(我下次跟你一样也是第二次参加,我就是你的对手了,加油!)

    如果对结果有任何异议,请回帖告知,我会认真复查。

回复列表 (共18个回复)

沙发

我的算法不知道行不行,,算法我想法,我不会实现,,,我的算法是这样的:
                     
                          if(n%2)偶数: 把n分解成(n/2-1)(n/2+1)
            if(n%2)偶数:
                          else奇数:把n分解成(n/2)(n/2)
输入一个N:                                                     进入循环n/2
    |        else奇数:把n分解为(n/2)(n/2+1);                       |
    |                                                              | 
    |______________________________________________________________|
上面建立二叉树

下面是访问这科二叉树了(我不知道怎么访问才可以全都反问到)
例如n=100;
                                 100
               49                                     51
         24             25                    25               26
     11       13    12        13        12        23      13         13
   5    6   6   7  5   7    6     7    5   7     11 12   6  7      6     7  
   这样一直下去 n>1;

第一次访问:100  
第二次访问:49     51  确定两个数的最大公约数是不是1;是1的话进行标记;
第三次访问:49     25   26确定三个数的最大公约数是否为1;标记........
第四次访问:49     25   13   13确定..........
............
>>>>.............................................................
...............................................................

一直下去,即使每次访问点的数之和为100;
把所有情况都访问到,再把所有标记为1
的进行比较大小..
不知道你们有没有明白我的意思,,,
我觉得这个是比较快的算法
但是我不知道怎么写出来

createTree(bt **T,int dat)
{
    if(dat==1)*T==NULL;
    else{
  if(dat%2==0)// 为偶数
  {
      if(dat/2%2==1)
      {
          *T=(bt *)malloc(sizeof(bt));
          (*T)->data=dat;
          createTree(&((*T)->lchild),dat/2);
          createTree(&((*T)->rchild),dat/2);
      }
      else {
           *T=(bt *)malloc(sizeof(bt));
          (*T)->data=dat;
          createTree(&((*T)->lchild),dat/2-1);
          createTree(&((*T)->rchild),dat/2+1);
      }
  }
  else {
          *T=(bt *)malloc(sizeof(bt));
          (*T)->data=dat;
          createTree(&((*T)->lchild),dat/2);
          createTree(&((*T)->rchild),dat/2+1);
  }
    }
    return 0;
}
这个是我建立二叉树的程序,不知道有没有错误




板凳


neverPE兄效率好高~~赞下

我感觉最近做生意  脑子有点白了- -


是我该死  是我白   哎   又忘记考虑周全了

3 楼

to wshong,你的思路和我一样,不过。。。

我觉得应该分解为素数。普通奇数之间很可能有公因子,因此你的奇数分解最后相乘在逻辑上可能有问题。

我觉得这个题目就是把N尽量分解为互不相同的若干素数,然后计算乘积。

4 楼

回1楼,分解后的若干个数,当最小公倍数最大,它们不一定互质。比如21,最好的分解是2+3+4+5+7,而不是互质的情况。

5 楼

我的思路有问题了,呵呵~

6 楼

哎~~~~~~ 
参加了3期,还没有一次能得到正确答案/。
汗一个,还要努力啊。

7 楼

[quote]回1楼,分解后的若干个数,当最小公倍数最大,它们不一定互质。比如21,最好的分解是2+3+4+5+7,而不是互质的情况。[/quote]

所以只能尽量。因为最后计算乘积的话,合数因子会对其他的质数因子产生影响,例如2、3、4、5、7中因为2是4的因子,因此2不能算,只能算4。

我的想法是,当对一个数N进行分解的时候,选择一个接近N/2而且与其他数不重复的质数,记为Z(2/N),另外一个数当然就是R = N - Z(2/N),Z(2/N)当然不会是其他数的因子,反之亦然,因此接下来测试R:

如果R是质数,且唯一,那么这种分解就成功了,如果不唯一,则失败;

如果存在一个其它的质数数Zt,使得Zt是R的因子,那么去掉Zt后分解成功;

如果存在一个其它的合数Ot,使得Ot是R的因子或者R是Ot的因子,就看N是否为质数,如果是,就不分解。如果不是,就保留R和Ot的大者,去掉因子。如果不存在其他的数与R有以上关系,则继续下一轮分解。还有一点就是如果Z*R<=N,则必须继续选取其他的Z和R。并且R不能为1。

例如对于21,
第一轮:
Z(2/N)=11,R=10,分解成功
(11、10)

第二轮:
对于11分解为Z=5,R=6,成功;
对于10分解为Z=5,R=5,质数5重复,因此继续选择Z和R。Z=3,R=7,成功
(5,6,3,7)

第三轮:
对于5分解为Z=2,R=3,由于质数3重复,所以5不能分解
对于6分解为Z=3,R=3,由于质数3重复,所以继续选择Z和R。Z=2,R=4,考虑到2是4的因子,因此去掉2,保留4。
对于3无法分解。
对于7分解为Z=3,R=4,4重复,而N=7为质数,因此不能分解
(5,[2],4,3,7)

第四轮分解
对于5,不能分解
对于2、3、7也不能分解
对于4,分解为Z=2、R=2,质数2重复,不能分解
(5,[2],4,3,7)为最终结果,其中[2]被去掉,不参与相乘。


8 楼

SonicLing : good work!

9 楼

这次错了,只有下次继续努力了。
每周五出题是吧,下次一定来报到哈!

10 楼

哦,原来我算法错了。

我来回复

您尚未登录,请登录后再回复。点此登录或注册