scau 1142 巡逻的士兵(分治)

1142 巡逻的士兵

时间限制:1000MS  内存限制:65536K
提交次数:217 通过次数:58

题型: 编程题   语言: G++;GCC

 

Description

有N个士兵站成一队列, 现在需要选择几个士兵派去侦察。
为了选择合适的士兵, 多次进行如下操作: 如果队列超过三个士兵, 那么去除掉所有站立位置为奇数的士兵, 
或者是去除掉所有站立位置为偶数的士兵。直到不超过三个战士,他们将被送去侦察。现要求统计按这样的方法,
总共可能有多少种不同的正好三个士兵去侦察的士兵组合方案。

注: 按上法得到少于三士兵的情况不统计。

1 <= N <= 2的32次方-1



输入格式

有多行,每行一个数字N,最后一行是0


输出格式

对每一行的数字N,输出针对N的方案数

直到没有数字


 

输入样例

10
4
0


 

输出样例

2
0
 
 
 
 
 
 
 
 
 
 
 
 
*****************************************************************************************************************

1.题意:将士兵分开,一直分到能游3个人一组的时候结束。

 

 

2.解题方法:本题为用分治的方法,将一个很大的数分成很小的数。当一个数为偶数的时候,可以将它分解成两个相等不部分,即一边是奇数一边是偶数。但是当那个数是个奇数的时候可以分成n/2n-n/2(注:在int型变量省略小数,所以n/2==(n-1)/2)

 

****************************************************************************************************************

具体例子分析:

                20

             |      |

             10      10  

            |   |   |   |

            5   5   5   5

           | |  | |  | | | |

      2 3 2 3  2 3 2 3

 

所以需要记录每一次分解左右的数,加起来就知道方案数

                   20(2+2)

                 |       |

               10(1+1)     10(1+1)  

              |    |      |    |

         5(1+0)  5(1+0)   5(1+0)  5(1+0)

           | |   | |     | |   | |

      2  3  2 3    2 3   2 3

*************************************************************************************************

 

要用上述的方法需要使用到函数的嵌套;

 

 

#include <stdio.h>
int select(unsigned n);
int main()
{
    unsigned n;<span style="font-family: Arial, Helvetica, sans-serif;">//n<2^32-1;用unsigned 可以防止溢出</span>

    while(scanf("%u",&n)!=EOF&&n)
    {
        printf("%d\n",select(n));
    }
    return 0;
}
int select(unsigned n)
{
    int left=0,right=0,sum=0;
    if(n==3)
        return 1;
    else if(n<3)
        return 0;
    else
    {
        if(n%2==0)//判断奇偶数
        {
            right=select(n/2);//右边的方案个数
            left=right;//偶数时,左右的方案个数相等
        }
        else
        {
            right=select(n/2);
            left=select(n-n/2);
        }
        sum=left+right;//计算总和
    }
    return sum;
}

虽然不是最快的方法,但是好理解一些

转载于:https://www.cnblogs.com/denghaiquan/p/6666090.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值