壮哉我大软六吧吧 关注:43贴子:895
  • 4回复贴,共1

【学术】C++实验三第三题

只看楼主收藏回复

五个正整数相加等于23,且五个数能组成1~23内的任意自然数,求这五个数。
这题好像很难的样子,做起来其实也挺轻松加愉快的~~~


1楼2013-01-07 14:57回复
    其实可以用枚举法做,因为1、2已经确定在五个数里面,最后一个数又可以通过其他4个数表示出来,我们不妨设5个数分别为1、2、a、b、c,其中1<2<a<b<c,那么我们仅需对a、b进行3~23的枚举就是了,这题很轻松就解决了~很轻松对吧O(∩_∩)O~~

    (╯`
    □′)╯┴—┴
    才怪!!别忘了我们除了枚举还要验证五个数能否组成1~23内的任意自然数,怎么办呢?一个一个试?不!我们用更高级的方法。。。一个一个加(  ̄▽ ̄)"。。。
    (/=ω=)/
    开玩笑的~我们可以采用位运算的方式(又是这个),我们知道(11111)2=(32)10,那么我们只需要从1数到32就能遍历每种相加情况(别问我为什么- -||),用这种方法能(很轻松地)遍历每种可能性,具体方法说起来太麻烦,大家自己思考一下吧~~~
    


    2楼2013-01-07 15:09
    回复
      2025-05-29 12:45:47
      广告
      锵锵~接下来放代码~(出乎意料的短呢。。。)
      #include <iostream>
      #include <stdlib.h>
      //这里是我偷懒,别学我!
      using std::cout;
      int main(){
      for(int a=3;a<23;a++)
      for(int b=a+1;b<23;b++)
      {
      int c = 20-a-b, count = 0;
      if(c<=a || c<=b) //令1<2<a<b<c
      break;
      bool flag[23];
      for(int i=0;i<23;i++) //初始化记录状态数组
      flag[i] = true;
      for(int i=1;i<32;i++)
      {
      //以二进制位表示每个数是否相加
      bool *f = flag + 1*((i&1)?1:0) + 2*((i&2)?1:0) + a*((i&4)?1:0) + b*((i&8)?1:0) + c*((i&16)?1:0) - 1;
      if(*f)
      {
      *f = false; //枚举每种可能的情况
      count++;
      }
      }
      if(count == 23)
      cout<<"1 2 "<<a<<" "<<b<<" "<<c<<"\n";
      }
      system("pause");
      }
      


      3楼2013-01-07 15:12
      收起回复
        这个留着以后看,记得我当时是枚举做的,比较小白


        IP属地:广东4楼2013-01-07 17:46
        回复