2021牛客暑期多校训练营8

2021牛客暑期多校训练营8

A. Ares, Toilet Ares

  • 题意

厕所战神,去厕所一次就有(frac{z_i - y_i}{z_i})的可能拿到一段长度为(x_i)的代码,只有代码长度累计到l时,即可通过题目(K),并且可以通过自己的智商解决a道简单题,求能完成题目的数量

  • 思路

(a+prod_{i=1}^n(z - y) / z)即可,注意逆元和分开求即可。

code :

void solve(){
    int n,m,k,a,l;
    cin >> n >> m >> k >> a >> l;
    ll d = a;
    ll up = 1, down = 1;;
    for(int i = 1;i <= k;i ++) {
        ll x,y,z;
        cin >> x >> y >> z;
        if(x == 0) continue;
        d = (d * z) % mod;
        up = up * (z - y) % mod;
        down = down * (pow_mod(z, mod - 2)) % mod;
    }
    ll ans = ((d + up) % mod + mod) * down % mod;
    cout << ans << endl;
}

D. OR

  • 题意

给出两个长度为(n - 1)的序列(b)(c),需要构造一个长度为n的序列a,要求(b_i = a_{i-1} or a_i, c_i = a_{i-1} + a_i), 问最多能构造出几个序列(a).

  • 思路

首先要知道定理: (a + b = a or b + a and b), 然后枚举(a_1)即可,判断是否可行即可。
思考一下,什么情况(a_{i-1})可以取一种或者两种,那么当

  1. ((a_i or a_{i-1} = 1) && (a_i and a_{i-1} = 1)),这样当前位(a_i)(a_{i-1})都是1
  2. 同时为0的情况也一样,只能为0
  3. ((a_i or a_{i-1} = 1) && (a_i and a_{i-1} = 0)),那么(a_i)(a_{i-1})就有两种选法(1,0)和(0,1).

code :

int b[N], c[N];
int a[N];
void solve(){
    int n;
    cin >> n;
    fep(i,2,n) cin >> b[i];
    fep(i,2,n) {
        cin >> c[i];
        c[i] -= b[i];
    }
    int ans = 1;
    fep(k,0,30) {
        int fa = 1,fb = 1;
        fep(i,2,n) {
            int tb = b[i] >> k & 1;
            int tc = c[i] >> k & 1;
            int na = 0, nb = 0;
            if(tb && tc) {
                nb = fb;
            }else if(tb && !tc) { // 顺序变了
                na = fb,nb = fa;
            }else if(!tb && !tc) {
                na = fa;
            }
            fa = na, fb = nb;
        }
        ans *= fa + fb;
    }
    
    cout << ans << endl;
}

E. Rise of Shadows

  • 题意

问你这一年可以是闰年且是素数嘛?

  • 思路

nonononono

code :

cout << "no" << endl;

F. Robots

  • 题意

给一张地图,问类型为(i)的机器人是否能从(st o ed)

  1. 只能向下走((x,y) o (x + 1,y))
  2. 只能想右走((x,y) o (x,y + 1))
  3. 都能走
  • 思路

暴力加bitset记忆化
从后往前扫,用列记录后面所有图的可达与否即可。

code:

bitset<N * N * 2> f[N];
int a[N][N];
char str[N];

struct Query{
    int x,y;
    int op,id;
};

vector<Query> v[N][N];
int ans[M];

void solve(){
    int n,m;
    cin >> n >> m;
    for(int i = 1;i <= n;i ++) {
        cin >> (str + 1);
        for(int j = 1;j <= m;j ++) {
            a[i][j] = (str[j] - '0');
        }
    }
    int q;
    cin >> q;
    for(int i = 1;i <= q;i ++) {
        int op,x1,y1,x2,y2;
        cin >> op >> x1 >> y1 >> x2 >> y2;
        v[x1][y1].push_back({x2,y2,op,i});
    }

    fpp(i,n,1) {
        fpp(j,m,1) {
            if(!a[i][j]) {
                if(!a[i][j + 1])
                    f[j] |= f[j + 1];
                f[j][i * m + j] = 1;
            }else {
                f[j].reset();
            }

            for(auto it : v[i][j]) {
                if(it.op == 2) ans[it.id] = (it.x == i);
                else if(it.op == 1) ans[it.id] = (it.y == j);
                else ans[it.id] = 1;
                ans[it.id] &= f[j][it.x * m + it.y]; 
            }
        }
    }
    fep(i,1,q) {
        if(ans[i]) cout << "yes" << endl;
        else cout << "no" << endl;
    }
}

K. Yet Another Problem About Pi

  • 题意

你有一条长为(pi)的线,你可以随意构造它的形状,变成圆都可以,然后给你一个(w)(d), 在二维平面内,每隔(w)有一条竖线,每隔(d)有一条横线,问你通过画线,最多可以和多少条线段相交(竖线和横线分开的)

  • 思路

枚举斜边的情况和直边的情况即可,直边的贡献是2,斜边的贡献是3,在图上画即可。

code :

void solve(){
    double w,d;
    cin >> w >> d;
    double hd = min(w,d);
    double hy = sqrt(w * w + d * d);
    int k = floor(pi / w);
    int ans = 0;
    for(int i = 0;i <= min(k,10);i ++) {
        if(pi - i * hd > 0) ans = max(ans, (int)(2 * i + (int)((pi - i * hd) / hy) * 3));
        if(pi - i * hy > 0) ans = max(ans, (int)(3 * i + (int)((pi - i * hy) / hd) * 2));
        
    }
    cout << ans + 4 << endl;
}
原文地址:https://www.cnblogs.com/darker-wxl/p/15120640.html