AtCoder Beginner Contest 171

比赛链接:https://atcoder.jp/contests/abc171/tasks

A - αlphabet

题意

给出一个字母,如果为大写输出 'A',如果为小写输出 'a' 。

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
    char c; cin >> c;
    cout << (isupper(c) ? 'A' : 'a');
}

B - Mix Juice

题意

从 $n$ 个数中选出 $k$ 个数之和的最小值。

题解

对前 $k$ 小的元素求和即可。

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
    int n, k; cin >> n >> k;
    int a[n] = {};
    for (int i = 0; i < n; i++)
        cin >> a[i];
    sort(a, a + n);
    cout << accumulate(a, a + k, 0);
}

C - One Quadrillion and One Dalmatians

题意

把一个数字转化为字母,规则为 $[1,26]$ 对应 $[a,z]$,$[27,702]$ 对应 $[aa,zz] \dots $ 。  

题解

转化为 $26$ 进制即可,需要注意每次取余前令 $n$ 减一来把 $[1,26]$ 映射到 $[0,25]$ 。

代码一

非递归实现:

#include <bits/stdc++.h>
using ll = long long;
using namespace std;
int main() {
    ll n; cin >> n;
    int bit[100] = {};
    int p = 0;
    while (n) {
        bit[p++] = (--n) % 26;
        n /= 26;
    }
    for (int i = p - 1; i >= 0; i--)
        cout << char(bit[i] + 'a');
}

代码二

递归实现:

#include <bits/stdc++.h>
using ll = long long;
using namespace std;

void solve(ll n) {
    if (n < 26)
        putchar(n + 'a');
    else {
        solve(n / 26 - 1);
        putchar(n % 26 + 'a');
    }
}

int main() {
    ll n; cin >> n;
    solve(n - 1);
}

D - Replacing

题意

给出 $n$ 个数和 $q$ 次操作,每次操作将 $n$ 个数中值为 $b$ 的数替换为 $c$,计算每次操作后 $n$ 个数的和。

题解

先对 $n$ 个数求和,每次操作总和的变化为 $(c-b)cnt_b$,之后更新 $cnt_b$ 和 $cnt_c$ 即可。

代码

#include <bits/stdc++.h>
using ll = long long;
using namespace std;
int main() {
    int n; cin >> n;
    ll ans = 0;
    map<int, int> cnt;
    for (int i = 0; i < n; i++) {
        int x; cin >> x;
        ans += x, cnt[x]++;
    }
    int q; cin >> q;
    for (int i = 0; i < q; i++) {
        int b, c; cin >> b >> c;
        ans += 1LL * (c - b) * cnt[b];
        cout << ans << "\n";
        cnt[c] += cnt[b], cnt[b] = 0;
    }
}

E - Red Scarf

题意

给出 $n$ 个数,计算每个数外 $n - 1$ 个数的异或值。

题解

利用 $x \oplus x = 0$ 的特性,先对所有数求一次异或,然后再对每个数求一次异或从总的异或值中抵消掉即可。

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
    int n; cin >> n;
    int a[n] = {};
    for (int i = 0; i < n; i++)
        cin >> a[i];
    int Xor = 0;
    for (int i = 0; i < n; i++)
        Xor ^= a[i];
    for (int i = 0; i < n; i++)
        cout << (Xor ^ a[i]) << ' ';
}

F - Strivore

题意

在一个小写字母串 $s$ 的任意位置插入一个小写字母 $k$ 次后可能得到多少不同的字符串。

题解

一个重要的结论是:答案与字符串 $s$ 无关,只与其长度有关,但是这个的证明想了一天也没有想明白。

那么可以将 $s$ 视为一个单一字母串,答案即 $\sum_{i = len_s}^{n} C_n^i \times 25^{n - i}$ 。

代码

#include <bits/stdc++.h>
using ll = long long;
using namespace std;
const int N = 2e6 + 10;
const int mod = 1e9 + 7;

ll fac[N], inv[N];

ll binpow(ll a, ll b) {
    ll res = 1;
    while (b) {
        if (b & 1) res = res * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res;
}

void init() {
    fac[0] = 1;
    for (int i = 1; i < N; i++) 
        fac[i] = fac[i - 1] * i % mod;
    inv[N - 1] = binpow(fac[N - 1], mod - 2);
    for (int i = N - 2; i >= 0; i--) 
        inv[i] = inv[i + 1] * (i + 1) % mod;
}

ll C(ll n, ll m) {
    return fac[n] * inv[m] % mod * inv[n - m] % mod;
}

int main() {
    init();
    int k; string s; cin >> k >> s;
    int n = k + s.size();
    ll ans = 0;
    for (int i = s.size(); i <= n; i++)
        ans += C(n, i) * binpow(25, n - i) % mod, ans %= mod;
    cout << ans << "\n";
}

 

posted @ 2020-06-22 21:10  Kanoon  阅读(315)  评论(0编辑  收藏  举报