题目详情:
N个人(编号1-N),站成一排,进行报数游戏。报数过程可能进行很多轮,有如下规则:
(1) 如果剩余人数不超过3个人,则游戏结束。
(2) 大家报数,然后留下报奇数的人继续游戏,或者留下报偶数的人继续游戏。
重复如此(1)(2)两步骤,到游戏结束。
问:最终剩下的三人组有多少种情况?(注意是三人组,例如如果最后剩下2个或者1个人,不计入结果中)。
输入n, (0<n<=10000000)
输出最终结果。
思路:根据题目知道有0,1,2人时有0种情况,有3人时有一种情况.
挑战1是意识到n个人,假如7个,抛去偶数人,剩下1,3,5,7号。这4个人再第二次游戏时相当于是1,2,3,4号,这意味这第二次游戏和直接进行一次4人游戏本质上是一致的。
挑战2是总结规律,这题的规律是:
这个公式有一个语言上的优化:if-else语句可以优化成这样:
或这样:
ans[i] = ans[i/2]+ans[(i+1)/2];
我觉得找规律的过程其实很简单,首先划分一下大的类别,在每个类别内踏踏实实的走一遍,规律自然就可以呈现出来了
代码:
#include<stdio.h> #define MAX 10000000 int ans[MAX + 1] = {0, 0, 0, 1,}; int flag = 0; void solve() { int i; for(i = 4; i <= MAX; i++) ans[i] = ans[i >> 1] + ans[(i + 1) >> 1]; flag = 1; } int howmany (int n) { if(!flag) solve(); return ans[n]; } //start 提示:自动阅卷起始唯一标识,请勿删除或增加。 int main() { printf("%d",howmany(0)); } //end //提示:自动阅卷结束唯一标识,请勿删除或增加。