BZOJ 1621 [Usaco2008 Open]Roads Around The Farm分岔路口:分治 递归

Posted Leohh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 1621 [Usaco2008 Open]Roads Around The Farm分岔路口:分治 递归相关的知识,希望对你有一定的参考价值。

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1621

题意:

  约翰的N(1≤N≤1,000,000,000)只奶牛要出发去探索牧场四周的土地。

  她们将沿着一条路走,一直走到三岔路口(可以认为所有的路口都是这样的)。

  这时候,这一群奶牛可能会分成两群,分别沿着接下来的两条路继续走。

  如果她们再次走到三岔路口,那么仍有可能继续分裂成两群继续走。

  奶牛的分裂方式十分古怪:如果这一群奶牛可以精确地分成两部分,这两部分的牛数恰好相差K(1≤K≤1000),那么在三岔路口牛群就会分裂。否则,牛群不会分裂,她们都将在这里待下去,平静地吃草。

  请计算,最终将会有多少群奶牛在平静地吃草。

 

题解:

  递归分治。

  

  答案为cal(n)。

  对于cal(a),有三种情况:

    (1)a <= k:

      当前牛群不可能再分裂,return 1。

    (2)a和k的奇偶性不同:

      奇数分成两部分,两部分之差一定为奇数。

      偶数分成两部分,两部分之差一定为偶数。

      所以若a和k的奇偶性不同,则不可能再分裂,return 1。

    (3)不属于上两种情况,可以继续分裂,return cal((a-k)/2)+cal((a-k)/2+k)。

 

AC Code:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 
 5 using namespace std;
 6 
 7 int n,k;
 8 
 9 int cal(int a)
10 {
11     if(a<=k) return 1;
12     if((k&1)!=(a&1)) return 1;
13     return cal((a-k)/2)+cal((a-k)/2+k);
14 }
15 
16 int main()
17 {
18     cin>>n>>k;
19     cout<<cal(n)<<endl;
20 }

 

以上是关于BZOJ 1621 [Usaco2008 Open]Roads Around The Farm分岔路口:分治 递归的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 1621 [Usaco2008 Open]Roads Around The Farm分岔路口:分治 递归

bzoj 1621: [Usaco2008 Open]Roads Around The Farm分岔路口dfs

bzoj1621 / P2907 [USACO08OPEN]农场周围的道路Roads Around The Farm

bzoj1622[Usaco2008 Open]Word Power 名字的能量*

BZOJ 1624 Usaco2008 Open Clear And Present Danger 寻宝之路

BZOJ1623 [Usaco2008 Open]Cow Cars 奶牛飞车 贪心