上海高校金马五校赛 D 数字游戏

版权声明:本文为博主原创文章,如需转载 评论区留名即可。 https://blog.csdn.net/calabash_boy/article/details/79954339

传送门

题意:给出两个区间[L1,R1] [L2,R2] 和一个模数mod ,两个人博弈,第一个人从区间1选出一个数字,第二个人从区间二选出一个数字,然后把第二个数字拼接到第一个数字后边,形成的新数字能被mod整除,则第二个人赢,否则第一个人赢,问第一个人是否必胜。

题解:拼出来的数字形如:A*10^lb+B。(lb为B的位数),这个数字对mod取模为 (A%mod)*(10^lb%mod)+(B%mod),由此可知:本质不同的A只有mod个,因为A%mod相同的时候,在B不变时,上式值相同。另本质不同的B也只有9*mod种(实际没有这么多),因为lb和B%mod相同的时候,在A不变时,上式值相同。我们的目标是让上式=0。因此可以先枚举本质不同的A,最多mod种,然后枚举B的长度lb,最多9种,然后我们就可以推算出B%mod的值,即可以O(1)查询是否有合法方案。只要存在一个A,没有合法的B使得上式=0,则A必胜。

Code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 2147483647;
 
int upper(int a, int b, int mod) {
  int rt = b / mod * mod + a % mod;
  if (rt < b) rt += mod;
  return rt;
}
int main() {
  int t;
  int A, B, C, D, mod;
  scanf("%d", &t);
  while (t--) {
    scanf("%d%d%d%d%d", &A, &B, &C, &D, &mod);
    bool win = false;
    for (int i = 0; i < mod; i++) {
      if (upper(i, A, mod) > B) continue;
 
      bool failed = false;
      for (int t = 1; t <= D; t *= 10) {
        int least = max(t, C);
        int best = min(10 * t - 1, D);
        if (least > best) continue;
 
        int rest = mod - i * 10 % mod * t % mod;
        if (upper(rest, C, mod) <= D) {
          failed = true;
          break;
        }
      }
      if (!failed) {
        win = true;
        break;
      }
    }
    if (win) printf("WIN\n");
    else printf("LOSE\n");
  }
  return 0;
}

阅读更多

没有更多推荐了,返回首页