首页 > 代码库 > ZOJ 3798--解题报告
ZOJ 3798--解题报告
题目相关:
3798相关链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5330
Alice和Bob玩数字游戏, 这次Alice和Bob玩的是绝对值游戏. (Alice和Bob以前只玩博弈类游戏, 现在开始玩数列了...)
Alice有n个数(分别是1~n), 然后Alice随机从N个数中取数, 组成一个数列{A(i)}.
Bob来构建{B(i)}数列, 满足如下规则:
{ B(1) = A(1) { B(i) = | A(i) - B(i-1) | (i>=2 && i<=n)
目标是:
所有序列中B(n)的最小值和最大值, 并且构造它们的一种可能序列.
思路分析:
可以猜测该题是规律题, 那么我们来找找规律, 看看其满足什么样的规律?
枚举2, 3, 4的情况
1). 当n=2时, (1, 2)的最小值为1(2, 1), 最大值为1(2, 1)
2). 当n=3时, (1, 2, 3)的最小值为0(3, 2, 1), 最大值为2(1, 2, 3)
3). 当n=4时, (1, 2, 3, 4)的最小值为0(4, 3, 2, 1), 最大值为4(3, 2, 1, 4)
B(n)的最小值, 可以构造序列{n, n-1, ..., 4, 3, 2, 1}, 观察得这必然是最小的序列之一.
再由奇偶性分析, 最后的差值由奇数个数决定, 奇数个时B(n)最小值为1, 偶数个时B(n)最小值为0, 验证和满足猜测.
同时我们可以大胆猜测, B(n)最大取值 = n - B(n - 1)<最小值>, 即 序列{ B(n) }={ 最小值 B(n -1 )序列, n }
AC代码:
#include <cstdio>// *) 找规律问题class game_t {public: int min_score(int n) { if ( ((n + 1) >> 1) & 0x01 ) { return 1; } return 0; } void solve(int n) { // *) 处理最小值/最大值 printf("%d %d\n", min_score(n), n - min_score(n - 1)); // *) 简单构造最小值 for ( int i = n; i > 1; i-- ) { printf("%d ", i); } printf("1\n"); // *) 简单构造最大值 for ( int i = n - 1; i > 0; i-- ) { printf("%d ", i); } printf("%d\n", n); }};int main(){ int n; game_t game; while ( scanf("%d", &n) != EOF ) { game.solve(n); } return 0;}
ZOJ 3798--解题报告