Codeforces Round 925 (Div. 3)

A

map<int, string> mp;
void solve()
{
 
    int n;
    cin >> n;
    cout << mp[n] << endl;
}

void init()
{    
	string ans(3, 'a');
    for (int i = 1; i <= 26; i++)
    {
        ans[0] = 'a' + i - 1;
        for (int j = 1; j <= 26; j++)
        {
            ans[1] = 'a' + j - 1;
            for (int k = 1; k <= 26; k++)
            {
                ans[2] = 'a' + k - 1;
                if (mp.find(i + j + k) == mp.end())
                    mp[i + j + k] = ans;
            }
        }
    }
}

B

模拟

void solve()
{
    int n;
    cin >> n;
    ll ave = 0, add = 0;
    vector<int> a(n + 1);
    for (int i = 1; i <= n; i++)
        cin >> a[i], ave += a[i];
    ave /= n;
    for (int i = 1; i <= n; i++)
    {
        if (a[i] >= ave)
            add += a[i] - ave;
        else
        {
            if (a[i] + add >= ave)
                add -= ave - a[i];
            else
            {
                cout << "NO" << endl;
                return;
            }
        }
    }
    cout << "YES" << endl;
}

C

分类讨论

void solve()
{
    int n;
    cin >> n;
    ll ave = 0, add = 0;
    vector<int> a(n + 1);
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    int ans = n;
    if (a[1] == a[n])
    {
        int l = 1, r = n;
        while (a[l] == a[1])
            l++;
        while (a[r] == a[n])
            r--;
        ans = min(ans, r - l + 1);
    }
    else
    {
        for (int i = 2; i <= n; i++)
            if (a[i] != a[1])
            {
                ans = min(ans, n - i + 1);
                break;
            }
        for (int i = n - 1; i >= 1; i--)
            if (a[i] != a[n])
            {
                ans = min(ans, i);
                break;
            }
    }
    cout << max(ans, 0) << endl;
}

D

分别维护模x/y下的数组,然后枚举j即可

void solve()
{
    int n, x, y;
    cin >> n >> x >> y;
    vector<int> a(n + 1), b(n + 1);
    map<pii, ll> mp;
    for (int i = 1; i <= n; i++)
    {
        int tmp;
        cin >> tmp;
        a[i] = tmp % x;
        b[i] = tmp % y;
    }
    ll ans = 0;
    for (int i = 1; i <= n; i++)
    {
        int fa = (x - a[i] + x) % x;
        int fb = (b[i] + y) % y;
        ans += mp[{fa, fb}];
        mp[{a[i], b[i]}]++;
    }
    cout << ans << endl;
}

E

能够影响数位和的操作只有类似800->8

所以Anna 一定会先反转后缀0多的数

Sasha一定会先合并后缀0多的数(100,10->10010)

将所有有后缀0的数取出,从大到小隔一个减去

void solve()
{
    int n, m, x, sum = 0;
    cin >> n >> m;
    vector<int> sz;
    for (int i = 1; i <= n; i++)
    {
        cin >> x;
        int bit = 0, ok = 1;
        while (x)
        {
            if (x % 10 == 0)
            {
                if (ok)
                    bit++;
            }
            else
                ok = 0;
            sum++;
            x /= 10;
        }
        if (bit)
            sz.push_back(bit);
    }
    sort(sz.begin(), sz.end());
    for (int i = (int)sz.size() - 1; i >= 0; i -= 2)
        sum -= sz[i];
    cout << (sum >= m + 1 ? "Sasha" : "Anna") << endl;
}

F

已知k组大小关系,判断是否矛盾

根据大小关系建边,然后拓扑排序,如果有环则说明矛盾

void solve()
{
    map<int, int> mp;
    int n, k;
    cin >> n >> k;
    vector<vector<int>> a(k + 1, vector<int>(n + 1, 0));
    vector<vector<int>> e(n + 1);
    vector<int> d(n + 1, 0);
    for (int i = 1; i <= k; i++)
        for (int j = 1; j <= n; j++)
        {
            cin >> a[i][j];
            if (j > 2)
            {
                e[a[i][j]].push_back(a[i][j - 1]);
                d[a[i][j - 1]]++;
            }
        }
    queue<int> q;
    for (int i = 1; i <= n; i++)
        if (!d[i])
            q.push(i);
    while (q.size())
    {
        auto t = q.front();
        q.pop();
        for (auto to : e[t])
            if (--d[to] == 0)
                q.push(to);
    }
    for (int i = 1; i <= n; i++)
        if (d[i])
        {
            cout << "NO" << endl;
            return;
        }
    cout << "YES" << endl;
}

G

首先注意到3只能在1的右边,2的左边,4只能在1的左边,2的右边,并且可以叠加

因此可以将问题抽象成\(a_1+a_2\)+1个盒子,放\(a_3+a_4\)个物品

运用隔板法公式即可

能够放\(a_3/a_4\)的盒子是总数的一半(如果总数是奇数要考虑两种情况)

注意判断无解是\(abs(a_1-a_2)> 1\)\(a_1==n \ and n>1\)\(a_2==n \ and n>1\)

const int N = 2e6 + 100, M = 25;
ll fac[N], invfac[N];
ll qmi(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()
{
    int n = 2e6;
    fac[0] = 1; // fac[i]表示i的阶乘,invfac[i]表示i的阶乘的逆元
    for (int i = 1; i <= n; i++)
        fac[i] = fac[i - 1] * i % mod;
    invfac[n] = qmi(fac[n], mod - 2); // 快速幂
    for (int i = n - 1; i >= 0; i--)
        invfac[i] = invfac[i + 1] * (i + 1) % mod;
    // C(n,m)=fac[n] * invfac[m] % mod * invfac[n - m] % mod;
}
ll C(int n, int m)
{
    if (n < m || m < 0 || n < 0) // 注意判断是否合法
        return 0;
    return fac[n] * invfac[m] % mod * invfac[n - m] % mod;
}
void solve()
{
    ll tot = 0;
    vector<int> a(5);
    for (int i = 1; i <= 4; i++)
        cin >> a[i], tot += a[i];
 
    if (a[3] == tot || a[4] == tot)
    {
        cout << 1 << endl;
        return;
    }
    if (a[1] == tot || a[2] == tot)
    {
        cout << (tot == 1 ? 1 : 0) << endl;
        return;
    }
    int sum = abs(a[1] - a[2]);
 
    if (sum > 1)
        cout << 0 << endl;
    else
    {
 
        ll ans = 0;
        int box = a[1] + a[2] + 1;
        if (!sum)
        {
            ll a1 = C(a[4] + box / 2, a[4]) * C(a[3] + box / 2 - 1, a[3]) % mod;
            ll a2 = C(a[3] + box / 2, a[3]) * C(a[4] + box / 2 - 1, a[4]) % mod;
            ans = (ans + a1 + a2) % mod;
            cout << ans << endl;
        }
        else
        {
            ll res = C(a[3] + box / 2 - 1, a[3]) * C(a[4] + box / 2 - 1, a[4]) % mod;
            ans = (ans + res) % mod;
            cout << ans << endl;
        }
    }
}
posted @ 2024-02-14 01:21  0x3ea  阅读(49)  评论(0编辑  收藏  举报