CF Round1043 Div.3

HoshiuZ
2025-08-22 / 0 评论 / 3 阅读 / 正在检测是否收录...

赛时 6/8.

A

根据题意模拟即可。

#include<bits/stdc++.h>
#define ll long long 

int T;

void solve() {
    int n, m;
    std::string a, b, c;
    std::cin >> n;
    std::cin >> a;
    std::cin >> m;
    std::cin >> b;
    std::cin >> c;
    for(int i = 0; i < m; i++) {
        if(c[i] == 'V') a = b[i] + a;
        else a = a + b[i];
    }
    std::cout << a << "\n";
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);

    std::cin>>T;

    while(T--) {
        solve();
    }
    
    return 0;
}

B

$y = 10^kx$ ,所以 $n = (10^k +1)x$,枚举 $k$ 即可求出 $x$ 与 $y$.

#include<bits/stdc++.h>
#define ll long long 

int T;

void solve() {
    ll n;
    std::cin >> n;
    std::vector<ll> ans;
    ll x = 10;
    while(x + 1 <= n) {
        if(n % (x + 1) == 0) ans.push_back(n / (x + 1));
        x *= 10;
    }
    sort(ans.begin(), ans.end());
    std::cout << ans.size() << "\n";
    for(auto x: ans) std::cout << x << " ";
    if(ans.size()) std::cout << "\n";
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);

    std::cin>>T;

    while(T--) {
        solve();
    }
    
    return 0;
}

C1

交易数量最少,所以按照三进制表示来交易即可。

#include<bits/stdc++.h>
#define ll long long 

int T;

ll qpow(ll x, ll y) {
    if(!y) return 1;
    ll t = qpow(x, y / 2);
    if(y & 1) return t * t * x;
    return t * t;
}

void solve() {
    ll n;
    std::cin >> n;
    ll x = 1, y = 0;
    while(x * 3 <= n) {
        x *= 3;
        y++;
    }
    ll ans = 0;
    while(n) {
        while(n >= x) {
            n -= x;
            ans += qpow(3, y + 1) + y * qpow(3, y - 1);
        }
        x /= 3;
        y--;
    }
    std::cout << ans << "\n";
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);

    std::cin>>T;

    while(T--) {
        solve();
    }
    
    return 0;
}

C2

一个 $x$ 可以换成 $3$ 个 $x-1$. 要求总个数不超过 $k$.
由 $\dfrac{3^{x+1} + x\cdot 3^{x - 1}}{3^x} = 3 +$ $\dfrac{ x }{3}$ ,所以发现 $x$ 越大,西瓜的单价越高。

且 $3^{x+1} + x\cdot 3^{x - 1} - 3\times (3^x +(x - 1)\cdot 3^{x - 2}) = 3^{x-1}$,所以 $x$ 越大,换成 $x-1$ 所减少的金币数越多。

于是先求出三进制表示,然后从高位来向下换即可。

#include<bits/stdc++.h>
#define ll long long 

int T;

ll qpow(ll x, ll y) {
    if(!y) return 1;
    ll t = qpow(x, y / 2);
    if(y & 1) return t * t * x;
    return t * t;
}

ll f(ll x) {
    ll res = 0;
    while(x) {
        res += x % 3;
        x /= 3;
    }
    return res;
}

void solve() {
    ll n, k;
    std::cin >> n >> k;
    if(n <= k) {
        std::cout << n * 3 << "\n";
        return ;
    } else if(k < f(n)) {
        std::cout << "-1\n";
        return ;
    } else {
        std::vector<ll> a;
        ll x = n;
        while(x) {
            a.push_back(x % 3);
            x /= 3;
        }
        std::reverse(a.begin(), a.end());
        ll t = f(n);
        int sz = a.size();
        for(int i = 0; i + 1 < sz; i++) {
            if(t + a[i] * 2 <= k) {
                t += a[i] * 2;
                a[i + 1] += 3 * a[i];
                a[i] = 0;
            } else {
                ll tmp = (k - t) / 2;
                t += tmp * 2;
                a[i + 1] += 3 * tmp;
                a[i] -= tmp;
            }
        }
        std::reverse(a.begin(), a.end());
        ll ans = 0;
        for(ll i = 0; i < sz; i++) {
            ans += a[i] * (qpow(3, i + 1) + i * qpow(3, i - 1));
        }
        std::cout << ans << "\n";
    }
    
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);

    std::cin>>T;

    while(T--) {
        solve();
    }
    
    return 0;
}

D

#include<bits/stdc++.h>
#define ll long long 

int T;

ll f(ll x) {
    if(x <= 0) return 0;
    ll tot = 0;
    ll i = 1;
    while(i <= x) {
        ll a = i * 10;
        ll b = x / a;
        ll c = x % a;
        tot += b * i * 45;
        ll d = c / i;
        tot += d * (c % i + 1);
        tot += i * (d - 1) * d / 2;
        i *= 10;
    }
    return tot;
}

ll ff(ll a, ll b) {
    if(a > b) return 0;
    return f(b) - f(a - 1);
}

void solve() {
    ll k;
    std::cin >> k;
    ll ans = 0, len = 1, cnt = 9, st = 1;
    while(k > 0) {
        ll tt = cnt * len;
        if(k >= tt) {
            ll end = st + cnt - 1;
            ans += ff(st, end);
            k -= tt;
            st = end + 1;
            cnt *= 10;
            len++;
        } else {
            ll a = k / len, b = k % len;
            ll end = st + a - 1;
            if(a > 0) {
                ans += ff(st, end);
            }
            if(b > 0) {
                ll c = st + a;
                std::string s = std::to_string(c);
                for(ll i = 0; i < b; i++) {
                    ans += s[i] - '0';
                }
            }
            k = 0;
        }
    }
    std::cout << ans << "\n";
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);

    std::cin>>T;

    while(T--) {
        solve();
    }
    
    return 0;
}

E

把 $a, b$ 放在一个数组里并从大到小排序。
对于一个询问 $x, y, z$,若前 $z$ 个数中原先在 $a$ 数组的数的个数小于 $x$, 且原先在 $b$ 数组的数的个数小于 $y$,那么答案就是前 $z$ 个数之和。否则,假设原先在 $a$ 数组的数的个数大于 $x$,那么答案就是 $a$ 数组的前 $x$ 个最大的数之和加上 $b$ 数组的前 $z-x$ 个数之和;反之同理。

#include<bits/stdc++.h>
#define ll long long 
#define N 200010

int T;

ll a[N], b[N], ca[N << 1], cb[N << 1], s[N << 1], sa[N], sb[N];

void solve() {
    ll n, m, q;
    std::cin >> n >> m >> q;
    for(int i = 1; i <= n; i++) {
        std::cin >> a[i];
    }
    for(int i = 1; i <= m; i++) {
        std::cin >> b[i];
    }
    
    std::sort(a + 1, a + n + 1);
    std::reverse(a + 1, a + n + 1);
    std::sort(b + 1, b + m + 1);
    std::reverse(b + 1, b + m + 1);

    for(int i = 1; i <= n; i++) {
        sa[i] = sa[i - 1] + a[i];
    }
    for(int i = 1; i <= m; i++) {
        sb[i] = sb[i - 1] + b[i];
    }
    int x = 1, y = 1;
    for(int i = 1; i <= n + m; i++) {
        if(x > n) {
            s[i] += b[y];
            ca[i] = 0;
            cb[i] = 1;
            y++;
        } else if(y > m) {
            s[i] += a[x];
            ca[i] = 1;
            cb[i] = 0;
            x++;
        } else if(a[x] > b[y]) {
            s[i] += a[x];
            ca[i] = 1;
            cb[i] = 0;
            x++;
        } else{
            s[i] += b[y];
            ca[i] = 0;
            cb[i] = 1;
            y++;
        }
    }
    for(int i = 1; i <= n + m; i++) {
        ca[i] += ca[i - 1];
        cb[i] += cb[i - 1];
        s[i] += s[i - 1];
    }

    for(int i = 1; i <= q; i++) {
        ll xx, yy, zz;
        std::cin >> xx >> yy >> zz;
        if(ca[zz] <= xx && cb[zz] <= yy) {
            std::cout << s[zz] << "\n";
        }
        else {
            if(ca[zz] > xx) {
                std::cout << sa[xx] + sb[zz - xx] << "\n";
            }
            else {
                std::cout << sb[yy] + sa[zz - yy] << "\n";
            }
        }
    }

    for(int i = 1; i <= n; i++) {
        a[i] = sa[i] = 0;
    }
    for(int i = 1; i <= m; i++) {
        b[i] = sb[i] = 0;
    }
    for(int i = 1; i <= n + m; i++) {
        ca[i] = cb[i] = s[i] = 0;
    }
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);

    std::cin>>T;

    while(T--) {
        solve();
    }
    
    return 0;
}
0

评论 (0)

取消