UPC Contest 1746 Stone Game

题目描述

Alice and Bob are always playing game! The game today is about taking out stone from the stone piles in turn.
There are n piles of stones, and the i-th pile contains A[i] stones.
As the number of stones in each pile differs from its neighbor’s, they determine to take out exactly one stone from one of them in one turn without breaking that property. Alice goes first.
The player who cannot take stone will lose the game.
Now you have to determine the winner given n numbers representing the piles, if they both play optimally.
You should notice that even a pile of 0 stone is still regarded as a pile!

输入

The first line of input file contains an integer T (1≤T≤100), describing the number of test cases.
Then there are 2×T lines, with every two lines representing a test case.
The first line of each test case contains only one integer n (1≤n≤105) as described above.
The second line of that contains exactly n numbers, representing the number of stone(s) in a pile in order.
All these numbers are ranging in [0,109].
It is guaranteed that the sum of n in all cases does not exceed 106.

输出

You should output exactly T lines.
For each test case, print Case d: (d represents the order of the test case) first, then print the name of winner, Alice or Bob .

样例输入

复制样例数据

2
2
1 3
3
1 3 1

样例输出

Case 1: Alice
Case 2: Bob

提示

Sample 1:
There is a possible stone-taking sequence: (1,3)-> (1,2)-> (0,2)-> (0,1)
Here is an invalid sequence: (1,3)-> (1,2)-> (1,1)-> (0,1). Though it has the same result as the first sequence, it breaks that property “the number of stones in each pile differs from its neighbor’s”.

题意:

           输入t组数据,每组数据包括2行,第一行输入一个n,表示石头的堆数,第二行输入n个数,分别表示每堆石头的个数。

Alice和Bob每个人每次只能取1个石头。如果出现相邻的两堆石头的数量相等时,则不能在取(一堆有0个石头的堆也算是一个堆)。Alice先手。

思路:

           从左到右,从右往左个扫描一遍,将石头堆序列进行转化(即把大小相对关系进行转化。如果其中的某一堆的石头a[i]的左右两边的两堆a[i+1],a[i-1]都比石头堆a[i]的石头多,那么堆a[i]最终会被取成0个,两边会按公差为1的等差数列递增)。

例如有10个数3 2 1 2 3 2 1 100 99 10最终转化成2 1 0 1 2 1 0 2 1 0

有种情况要考虑,例如这组样例

10个数1 2 3 4 5 6 3 2 9 10最终转化成0 1 2 3 4 5 1 0 1 2

石头个数为6的石头堆为峰值,其左边递增的数比右边递减的数多,那么他至少是5所以从右边往左边扫描的时候要进行比较大小。

然后看从初始每堆石头的个数到转化后总共需要 被取走多少个石头。如果总个数为奇数则Alice胜利,否则Bob胜利。

#include<iostream>
using namespace std;
int a[110000],b[110000];
int main()
{
    int t;
    cin>>t;
    for(int j=1;j<=t;j++)
    {
        int n;
        long long ans=0;
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            ans+=a[i];//把初始状态的石头全加起来
        }
        b[1]=0;
        for(int i=2;i<=n;i++)//从左往右扫描,把递增序列找出来,并且用数组b记录转化以后的石头堆的个数
        {
            if(a[i]>a[i-1])
            {
                b[i]=b[i-1]+1;
            }
            else
                b[i]=0;
        }
        for(int i=n-1;i>=1;i--)//从右往左扫描,把递减序列找出来。
        {
            if(a[i]>a[i+1])
            {
                b[i]=max(b[i],b[i+1]+1);
            }
            ans-=b[i];
        }
        ans-=b[n];
        cout<<"Case "<<j<<": ";
        if(ans%2)
            cout<<"Alice";
        else
            cout<<"Bob";
        if(j!=t)
            cout<<endl;
    }
    return 0;
}

     

猜你喜欢

转载自blog.csdn.net/ytuyzh/article/details/89763417