Flip coins

  1. 一个关于翻硬币的问题,
    一摞硬币共 有m枚,每一枚都是正面朝上。取下最上面的一枚硬币,将它翻面后放回原处。然后取下最上面的2枚硬币,将他们一起翻面后再放回原处。再取3枚,取4枚…… 直至m枚。然后再从这摞硬币最上面的一枚开始,重复刚才的做法。这样一直做下去,直到这摞硬币中的每一枚又都是正面朝上为止。例如,m为1时,翻两次即 可。m为2时,翻3次即可;m为3时,翻9次即可;m为4时,翻11次即可;m为5时,翻24次即可;…;m为30时,翻899次即可;…
    输 入:
      仅有的一个数字是这摞硬币的枚数m,0<m<1000。
      输 出:
      为了使这摞硬币中的每一枚又都是正面朝上所必需翻的次数。
      某单元输入:
          30

  2. /*
  3.  * 翻硬币
  4.  * tanliboy 23.Nov 2008
  5.  */
  6. #include<iostream>
  7. #include<bitset>
  8. using namespace std;
  9. int n;
  10. bool* data;
  11. int partFlip()
  12. {
  13.     bool term = false;
  14.     int cnt = 0;
  15.     for(int i=1;i<n;i++)
  16.     {
  17.         if(!term && data[i-1] != data[i])
  18.         {
  19.             continue;
  20.         }else if(data[i] == false)
  21.         {
  22.             if(false == term)
  23.             {
  24.                 term  = true;
  25.                 cnt = i-1;
  26.             }
  27.         }else
  28.         {
  29.             return -1;
  30.         }
  31.     }
  32.     if(false == term)
  33.     {
  34.         cnt = data[n-1] == false ? n-1 : n;
  35.     }
  36.     return cnt;
  37. }
  38. void flip()
  39. {
  40.     bool* orig = new bool[n];
  41.     for(int i = 0;i<n;i++)
  42.     {
  43.         orig[i] = data[i];
  44.     }
  45.     for(int i = 0;i<n;i++)
  46.     {
  47.         if(i%2 ==0)
  48.         {
  49.             data[i/2] = !orig[n-1-i];
  50.         }else
  51.         {
  52.             data[n-1-i/2] = orig[n-1-i];
  53.         }
  54.     }
  55.     delete[] orig;
  56. }
  57. int main()
  58. {
  59.     cin>>n;
  60.     data = new bool[n];
  61.     for(int i = 0;i<n;i++)
  62.     {
  63.         data[i] = false;
  64.     }
  65.     int count = n;
  66.     flip();
  67.     do  
  68.     {
  69.         int p = partFlip();
  70.         if(p>=0)
  71.         {
  72.             count += p;
  73.             break;
  74.         }else
  75.         {
  76.             flip();
  77.             count += n;
  78.         }
  79.     }while(true);
  80.     cout<<count<<endl;
  81.     delete[] data;
  82.     return 0;
  83. }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值