Educational Codeforces Round 107 (Rated for Div. 2) 个人题解(A~D)

补题链接:Here

1511A. Review Site

题意:\(n\) 个影评人,\(a_i\) 有三种类型,如下

  • \(a_i = 1\) ,则表示支持
  • \(a_i = 0\) ,则表示不支持
  • \(a_i = 3\) ,则表示无所谓

现在求最大的支持数。

思路:把 \(a_i = 1,3\) 的累加即可

1511B. GCD Length

给定位数 \(a,b\)\(gcd(a,b) = c\)

求出 \(x,y\)

思路:保持最高位基本一致为 \(1\) ,接下来取 \(0\) 这样一定可以得到 gcd(x,y) = c

比赛的时候的猜想,现在证明不出来。。。

void solve() {
    int a, b, c;
    cin >> a >> b >> c;
    for (int i = 0; i <= a - c; ++i) cout << 1;
    for (int i = 1; i < c; ++i) cout << 0;
    cout << " 1";
    for (int i = 1; i < b; ++i) cout << 0;
    cout << "\n";
}

1511C. Yet Another Card Deck

题意:给定 \(n\) 张卡牌和 \(q\) 次操作,每次操作要执行输出下标(从1开始)、把该卡片放置最前面

由于卡牌种类仅 \(50\) 种,所以我可以枚举和变化下标

详细见代码

void solve() {
    int n, q;
    cin >> n >> q;
    vector<int> a(n), idx(51);
    for (int &x : a) cin >> x;
    for (int i = n - 1; i >= 0; --i) idx[a[i]] = i;
    for (int i = 0, t; i < q; ++i) {
        cin >> t;
        cout << idx[t] + 1 << " ";
        for (int j = 1; j <= 50; ++j)
            if (j != t && idx[j] < idx[t]) idx[j]++; // 使原本在此卡牌之前的牌往后移
        idx[t] = 0;
    }
}

另外看了下其他dalao的代码想起可以用树状数组做

1511D. Min Cost String

由于要满足 \(k\) 次 cost,只要贪心拼接即可

void solve() {
    int n, k;
    cin >> n >> k;
    string s;
    for (int i = 0; i < k; i++) {
        s += 'a' + i;
        for (int j = i + 1; j < k; j++) {
            s += 'a' + i;
            s += 'a' + j;
        }
    }
    // assert(s.size() == k * k);
    for (int i = 0; i < n; i += 1) cout << s[i % s.size()];
}

1511E. Colorings and Dominoes

没怎么懂这么题,先贴一下学长的代码

void solve() {
    int n, m;
    cin >> n >> m;
    vector<string> vs(n);
    for (int i = 0; i < n; ++i) cin >> vs[i];
    int k = n * m;
    vector<ll> pw(k + 1), ans(k + 1), pv(k + 1);
    for (int i = 0; i <= k; ++i) pw[i] = i ? pw[i - 1] * 2 % mod : 1;
    for (int i = 0; i <= k; ++i) pv[i] = i ? pv[i - 1] * (mod + 1) / 2 % mod : 1;
    ll sum = 0;
    for (int i = 1; i <= k; ++i) {
        if (i >= 3 and i % 2) sum = (sum + pv[i]) % mod;
        ans[i] = (ans[i - 1] * 2 + pw[i] * sum + (i % 2 == 0)) % mod;
        //cout << i << " " << ans[i] << "\n";
    }
    int w = 0;
    for (auto s : vs)
        for (char c : s) w += c == 'o';
    ll res = 0;
    for (int i = 0; i < n; ++i) {
        int p = 0;
        for (int j = 0; j <= m; ++j)
            if (j < m and vs[i][j] == 'o') p++;
            else {
                res = (res + ans[p] * pw[w - p]) % mod;
                p   = 0;
            }
    }
    for (int i = 0; i < m; i++) {
        int p = 0;
        for (int j = 0; j <= n; j++)
            if (j < n and vs[j][i] == 'o') p++;
            else {
                res = (res + ans[p] * pw[w - p]) % mod;
                p   = 0;
            }
    }
    cout << res;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值