首页 > 代码库 > Codeforces Round #281 (Div. 2)

Codeforces Round #281 (Div. 2)

这场题也不难。


不过自己一直犯逗。 不是题目看错就是数组开小。

A,B,C,D都还挺水的,E其实也挺简单,只不过我当时没想明白。。


C的话, 枚举所有可能的d即可,复杂度是排序的nlogn


D的话, 对于奇数来说,黑方只需要跟白方对称走就一定能赢

偶数的话, 白方往1,2走一步就变成了奇数的情况,然后黑方咋走,白方就对称走就行。所以最后白方一定能赢


E

对于给出的t, a, b

我们先把特判的搞定,

无非是t = 1,a=1的情况

根据b是否等于1来特判


然后其他情况就要看方程了

a0+a1t+a2t^2+...=a

a0+a1a+a2a^2+...=b


然后移项得

a1+a2t + a3t^2+...=  (a-a0)/t

a1+a2a + a3a^2+...=(b-a0) /a

会发现这个问题是可以递归解的。

这里a0的值有要求

(a-a0) %t ==0

(b-a0)%a==0

也就是说a0%a == b % a,  a0 % t == a % t

然后就发现其实枚举a0的量非常少

对于a0%a == b%a有a0= k * a + b %a0

a0 <= b && a0 <= a

会发现k=0或者1,而且必须满足a0 % t == a % t


然后接下来就是递归了。就得出答案了



#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#include <algorithm>
#include <map>
#define MAXN 55555
#define MAXM 222222
#define INF 1000000001
using namespace std;
int gao(long long a, long long b, long long c, long long d) {
    if(b == 0 && d == 0) return 1;
    if(b == 0 || d == 0) return 0;
    long long ans = 0;
    for(long long i = 0; i <= 1; i++) {
        long long a0 = i * c + d % c;
        if(a0 > b || a0 > d) break;
        if((b - a0) % a == 0) {
            ans += gao(a, (b - a0) / a, c, (d - a0) / c);
        }
    }
    return ans;
}
int main() {
    long long t, a, b;
    scanf("%I64d%I64d%I64d", &t, &a, &b);
    if(t == 1 && a == 1) {
        if(b == 1) {
            puts("inf");
        } else puts("0");
    } else printf("%d\n", gao(t, a, a, b));
    return 0;
}



Codeforces Round #281 (Div. 2)