洛谷P4702取石子

算法:前缀和

原题

洛谷 P4702 取石子

题目描述

Alice 和 Bob 在玩游戏。

他们有 n n n 堆石子,第 i i i 堆石子有 a i a_i ai 个,保证初始时 a i ≤ a i + 1 ( 1 ≤ i < n ) a_i \leq a_{i + 1}(1 \leq i < n) aiai+1(1i<n)。现在他们轮流对这些石子进行操作,每次操作人可以选择满足 a i > a i − 1 a_i > a_{i - 1} ai>ai1 a 0 a_0 a0 视为 0 0 0)的一堆石子,并从中取走一个。谁最后不能取了谁输。Alice 先手,他们都使用最优策略,请判断最后谁会取得胜利。

输入格式

第一行一个整数 n ( 1 ≤ n ≤ 100 ) n(1 \leq n \leq 100) n(1n100),表示石子堆数。

接下来一行 n n n 个数,第 i i i 个数为 a i ( 1 ≤ a i ≤ 1 0 9 ) a_i(1 \leq a_i \leq 10^9) ai(1ai109),意义如上所述。

输出格式

“Alice” 或 “Bob”,表示谁会赢。

输入输出样例 #1

输入 #1
1
1
输出 #1
Alice

输入输出样例 #2

输入 #2
1
2
输出 #2
Bob

思路

根据题意,可以提炼三个关键条件:

  1. 对于输入的数据, a i ≤ a i + 1 a_i \leq a_{i + 1} aiai+1始终成立,即前一个数一定小于等于后一个数
  2. a i > a i − 1 a_i > a_{i - 1} ai>ai1是取石头的条件
  3. 最重要的条件是 a 0 = 0 a_0=0 a0=0

现先根据条件3考虑特殊情况 a 0 = 0 a_0=0 a0=0 a 1 ≠ 0 a_1\neq0 a1=0,该情况与条件2综合考虑, a 1 a_1 a1中的石头无论多少,就算是最少的1块石头,也满足条件2,可以被取走一块,最后都可以被取完,也就是最后 a 1 = 0 a_1=0 a1=0,一定成立。

那么,对于任意两堆石头,只要前一堆石头数量为0,后一堆石头数量最终一定会被取完,而且 a 0 = 0 a_0=0 a0=0,最后所有的石头都会被取完,即 a i = 0 ( 1 ≤ i ≤ n ) a_i=0 (1\leq i \leq n) ai=0(1in),问题转换为计算石头的总数量,又因为Alice先取,那么石头的数量为奇数,就是Alice获胜,数量为偶数,就是Bob获胜。

算法使用

计算石头总数量的时候,可以使用前缀和方法

注意

本题的数据范围是 1 ≤ n ≤ 100 1 \leq n \leq100 1n100 1 ≤ a i ≤ 1 0 9 1\leq a_i\leq10^9 1ai109,最后数量和的数量级最大是 1 0 1 1 10^11 1011,那么sum[]数组应该使用long long数据类型

代码

#include 

int n, i;
int arr[100];
long long sum[100];

int main() 
{
    scanf("%d", &n);
    for(i = 1; i <= n; i++) {
        scanf("%d", &arr[i]);
    }

    sum[1] = arr[1];
    for(i = 2; i <= n; i++) {
        sum[i] = sum[i - 1] + arr[i];
    }

    if(sum[n] % 2 == 1) {
        printf("Alice");
    } else {
        printf("Bob");
    }
    return 0;
}

你可能感兴趣的:(个人算法练习,算法,学习)