Gym - 102821G Game of Primes (博弈)

Alice and Bob always like playing games with each other and today they found a new game about primes.

There are two positive integers xx and yy in the game, and Alice and Bob move in turn. At each turn, the current player can choose one integer and subtract it by 11 (making (x,y)to (x−1,y) or to (x,y−1)). The game ends when one of following conditions is met and the winner is specified at the same time:

  • When xx or yy equals to KK: Bob wins.
  • When xx and yy are both primes: Alice wins.
  • When both of the previous conditions are satisfied at the same time: Bob wins.

Now xx, yy, KK and who moves first are given, can you determine who will finally win the game if they both play optimally?

Input

The first line of input contains an integer TT, representing the number of test cases. Then following TTlines and each line contains one test case.

For each test case, there are four integers xx, yy, KK and ww separated by exactly one space. xx,yy,KK are mentioned above. w=0w=0 when Alice moves first and w=1w=1 when Bob moves first.

Output

For each test case, you should output Case xx: name in one line, where xx indicates the case number starting from 1, and name is the player who will win the game.

Example

Input

4
4 9 2 0
7 10 2 0
6 39 2 0
5 28 2 0

Output

Case 1: Alice
Case 2: Alice
Case 3: Alice
Case 4: Bob

Note

1≤T≤100

2≤x,y≤10^6

2≤K≤min(x,y)

0≤w≤1

For 90% test cases: max(x,y)≤1000

题意:初始有两个数 x 和 y,每次操作可以选择一个数减1,Alice和Bob轮流操作,指定某人先手,

(1)如果某时刻 x == k 或 y == k,Bob胜

(2)如果某时刻 x、y都是素数,Alice胜

(3)如果(1)(2)同时满足,Bob胜

思路:Alice需要两个都大于k的素数才能获胜,如果Bob先手,只要存在两个距离x、y相等的素数,Alice就可以获胜,因为Bob无论减哪个,Alice减另一个就可以了

Alice先手的话,让Alice随便选一个减,就转化为了Bob先手

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 7;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

int pri[N], tot;
bool vis[N];

void init() {
    for(int i = 2; i < N; ++i) {
        if(!vis[i]) pri[++tot] = i;
        for(int j = 1; j <= tot; ++j) {
            if(i * pri[j] > N) break;
            vis[i * pri[j]] = 1;
            if(i % pri[j] == 0) break;
        }
    }
}

bool check(int x, int y, int k) {
    set<int>st;
    for(int i = x; i > k; --i)
        if(!vis[i]) st.emplace(x - i);
    for(int i = y; i > k; --i)
        if(!vis[i] && st.count(y - i))
            return 1;
    return 0;
}

int main() {
    init();
    int t, x, y, k, w, kcase = 0;
    scanf("%d", &t);
    while(t--) {
        scanf("%d%d%d%d", &x, &y, &k, &w);
        printf("Case %d: ", ++kcase);
        if(x == k || y == k) {
            printf("Bob\n");
            continue;
        }
        if(!vis[x] && !vis[y]) {
            printf("Alice\n");
            continue;
        }
        if(w) {
            if(check(x, y, k)) printf("Alice\n");
            else printf("Bob\n");
        }
        else {
            if(check(x - 1, y, k) || check(x, y - 1, k)) printf("Alice\n");
            else printf("Bob\n");
        }
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值