题意:给出两个区间[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;
}