Codeforces 346A Alice and Bob

龍威昊發表於2019-05-10

Alice and Bob

time limit per test:2 seconds
memory limit per test:256 megabytes
input:standard input
output:standard output

Problem Description

It is so boring in the summer holiday, isn`t it? So Alice and Bob have invented a new game to play. The rules are as follows. First, they get a set of n distinct integers. And then they take turns to make the following moves. During each move, either Alice or Bob (the player whose turn is the current) can choose two distinct integers x and y from the set, such that the set doesn`t contain their absolute difference |x - y|. Then this player adds integer |x - y| to the set (so, the size of the set increases by one).

If the current player has no valid move, he (or she) loses the game. The question is who will finally win the game if both players play optimally. Remember that Alice always moves first.

Input

The first line contains an integer n (2 ≤ n ≤ 100) — the initial number of elements in the set. The second line contains n distinct space-separated integers a1, a2, …, an (1 ≤ ai ≤ 10^9) — the elements of the set.

Output

Print a single line with the winner`s name. If Alice wins print “Alice”, otherwise print “Bob” (without quotes).

Sample Input

2
2 3
2
5 3
3
5 6 7

Sample Output

Alice
Alice
Bob

Hint

Consider the first test sample. Alice moves first, and the only move she can do is to choose 2 and 3, then to add 1 to the set. Next Bob moves, there is no valid move anymore, so the winner is Alice.


http://codeforces.com/problem…


Accepted Code

// Author : Weihao Long
// Created : 2017/12/16

#include "stdio.h"

int gcd(int m, int n) {
    int  ans, r = m % n;
    if (r == 0)
        ans = n;
    else
        ans = gcd(n, r);
    return ans;
}

int main() {
    int n;
    while (scanf("%d", &n) != EOF) {
        int a[100];
        for (int i = 0; i < n; i++)
            scanf("%d", &a[i]);
        for (int j = 1; j < n; j++)
            for (int k = 0; k < n - j; k++)
                if (a[k] > a[k + 1]) {
                    int tmp = a[k];
                    a[k] = a[k + 1];
                    a[k + 1] = tmp;
                }
        int max = a[n - 1];
        int head = a[0];
        for (int u = 1; u < n; u++)
            head = gcd(a[u], head);
        int x = max / head - n;
        puts(x % 2 ? "Alice" : "Bob");
    }
    return 0;
}

Notes

題意:
兩人在現有數字中分別挑一個數,計算 |x – y| ,若該數還不存在,則新增上去,如果無論怎樣計算 |x – y| ,都在現有數字中能找到,遊戲就結束了。如果新增奇數個數字,則 Alice 贏,否則 Bob 贏。

思路:
1.先找規律,就拿短的試試“1,3,5,7”、“2,4,6,8”、“3,6,9,12”、“3,4,5,6”。
2.試了幾組資料,答案都是首項等於公差的等差數列 { d, 2d, 3d, 4d … } 。
3.猜測最終狀態都形如此。
4.如果知道了最終數列的首項(公差),又知道數列中最大的數,這個數列最終有多少個元素就可以算出來了。
5.問題轉化為求首項,也即求“最終數列裡所有數的最大公約數”。

演算法:
第一步:將初始的數字按升序排列。
第二步:初始狀態,數列的首項就暫時設為最小的 a0 。
第三步:遍歷初始數列,求當前的首項與 ai 的最大公約數,並更新首項。(這步最關鍵,目的是求“最終數列裡所有數的最大公約數”)
第四步:計算最終數列元素個數與初始時的差值,即為後來增添的數字個數。

感受:
第一次提交是錯的,當時我以為最終狀態就是一個從 1 到 max 的序列(由題目的樣例資料得來的)。後來多試了幾組資料,發現“2,4,6,8”就不是,然後才發現是最終狀態都是等差數列,並且首項等於公差。按這個想法試了一下就過了。

相關文章