Codeforces Round #785 (Div. 2)

CF系列题解


题目

A. Subtle Substring Subtraction

原题链接

A. Subtle Substring Subtraction

题意

Alice 和 Bob 玩游戏,给定一个由小写字母组成的字符串,每次 Alice 可以选择长度为偶数的子串,Bob 可以选择长度为奇数的子串,其中 a 对应 1 1 1 分,b 对应 2 2 2 分,以此类推。两人均采用最佳策略且 Alice 先手,问每轮的胜利者是谁并且得分相差绝对值是多少。

输入格式
第一行包含一个整数 t ( 1 ≤ t ≤ 5 ⋅ 1 0 4 ) t (1≤t≤5⋅10^4) t(1t5104) ,表示有t组测试数据。
每个测试数据第一行包含一个字符串 s ( 1 ≤ ∣ s ∣ ≤ 2 ⋅ 1 0 5 ) s (1≤|s|≤2⋅10^5) s(1s2105)
字符串总长度不超过 2 ⋅ 1 0 5 2⋅10^5 2105

输出格式
胜利者的名字以及二者的分数差的绝对值

输入样例:

5
aba
abc
cba
n
codeforces

输出样例:

Alice 2
Alice 4
Alice 4
Bob 14
Alice 93

题解

思路

由于采用最佳策略,因此倘若字符串长度为偶数,Alice 一定会直接拿完,否则的话其会舍弃头或尾的字符(取决于哪个大)。

细节见代码。

代码

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

void solve()
{
    string s;
    cin >> s;
    int n = s.size();
    int a = 0, b = 0;
    vector<int> q(n + 1);
    for (int i = 1; i <= n; i ++ ) q[i] = s[i - 1] - 'a' + 1;
    // 此处直接用前缀和做了,直接枚举也是可以的
    for (int i = 1; i <= n; i ++ ) q[i] += q[i - 1];
    if (n % 2) {
        int t = max(q[n] - q[1], q[n - 1]);
        a += t;
        b += q[n] - t;
    } else {
        a += q[n];
    }

    if (a > b) {
        cout << "Alice " << abs(a - b) << "\n";
    } else {
        cout << "Bob " << abs(a - b) << "\n";
    }
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int T;
    cin >> T;

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

    return 0;
}

B - A Perfectly Balanced String?

原题链接

B - A Perfectly Balanced String?

题意

给定一个字符串 s s s,我们规定 ( t , u , v ) (t,u,v) (t,u,v),其中 t t t s s s 的子串, u u u v v v s s s 的其中一个字符,问对于 s s s 的所有类似的三元组,是否满足 u u u v v v t t t 中出现的次数之差的绝对值小于等于 1 1 1

输入格式
第一行包含一个整数 t ( 1 ≤ t ≤ 2 ⋅ 1 0 4 ) t (1≤t≤2⋅10^4) t(1t2104) ,表示有t组测试数据。
每个测试数据包含一个字符串 s ( 1 ≤ ∣ s ∣ ≤ 2 ⋅ 1 0 5 ) s (1≤|s|≤2⋅10^5) s(1s2105)
字符串长度的总和不超过 2 ⋅ 1 0 5 2⋅10^5 2105

输出格式
若能满足要求输出 YES,否则输出 NO

输入样例:

5
aba
abb
abc
aaaaa
abcba

输出样例:

YES
NO
YES
YES
NO

题解

思路

倘若字符串 s s s 中存在 c n t cnt cnt 个不同的字母,那么对于原串的前缀,即 [ 1 , c n t ] [1,cnt] [1,cnt] 中每个字母必须出现一次,且对于 c n t cnt cnt 之后的部分,一定要是重复出现 [ 1 , c n t ] [1,cnt] [1,cnt] 这一段的内容,即 [ 1 , c n t ] = [ c n t + 1 , 2 × c n t ] [1, cnt] = [cnt+1, 2×cnt] [1,cnt]=[cnt+1,2×cnt],倘若不满足其中一个条件,即为不合法。

求不同元素和对于 [ 1 , c n t ] [1,cnt] [1,cnt] 的判重偷懒用的全是 s e t set set

无证明。

代码

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

void solve()
{
    string s;
    cin >> s;

    set<char> S;
    for (int i = 0; i < s.size(); i ++ ) S.insert(s[i]);

    int cnt = S.size();
    set<int> w;
    for (int i = 0; i < cnt; i ++ ) w.insert(s[i]);
    if (w.size() != cnt) {
        cout << "NO\n";
        return;
    }
    for (int i = cnt; i < s.size(); i ++ ) {
        if (s[i % cnt] != s[i]) {
            cout << "NO\n";
            return;
        }
    }
    cout << "YES\n";
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int T;
    cin >> T;

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

    return 0;
}

C. Palindrome Basis

原题链接

C. Palindrome Basis

题意

给定一个数 n n n,他能被若干个回文数相加而成,问由多少种方案。

回文数:1,2,3,4,5,6,7,8,9,11,22,33,44,55,66,77,88,99,101,111...

输入格式
第一行包含一个整数 t ( 1 ≤ t ≤ 1 0 4 ) t (1≤t≤10^4) t(1t104) ,表示有t组测试数据。
每个测试数据包含一个整数 n ( 1 ≤ n ≤ 4 ⋅ 1 0 4 ) n (1≤n≤4⋅10^4) n(1n4104)

输出格式
方案数

输入样例:

2
5
12

输出样例:

7
74

题解

思路

完全背包求方案,预处理出来即可。

代码

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

constexpr int P = 1e9+7;
using i64 = long long;
// assume -P <= x < 2P
int norm(int x) {
    if (x < 0) {
        x += P;
    }
    if (x >= P) {
        x -= P;
    }
    return x;
}
template<class T>
T power(T a, int b) {
    T res = 1;
    for (; b; b /= 2, a *= a) {
        if (b % 2) {
            res *= a;
        }
    }
    return res;
}
struct Z {
    int x;
    Z(int x = 0) : x(norm(x)) {}
    int val() const {
        return x;
    }
    Z operator-() const {
        return Z(norm(P - x));
    }
    Z inv() const {
        assert(x != 0);
        return power(*this, P - 2);
    }
    Z &operator*=(const Z &rhs) {
        x = i64(x) * rhs.x % P;
        return *this;
    }
    Z &operator+=(const Z &rhs) {
        x = norm(x + rhs.x);
        return *this;
    }
    Z &operator-=(const Z &rhs) {
        x = norm(x - rhs.x);
        return *this;
    }
    Z &operator/=(const Z &rhs) {
        return *this *= rhs.inv();
    }
    friend Z operator*(const Z &lhs, const Z &rhs) {
        Z res = lhs;
        res *= rhs;
        return res;
    }
    friend Z operator+(const Z &lhs, const Z &rhs) {
        Z res = lhs;
        res += rhs;
        return res;
    }
    friend Z operator-(const Z &lhs, const Z &rhs) {
        Z res = lhs;
        res -= rhs;
        return res;
    }
    friend Z operator/(const Z &lhs, const Z &rhs) {
        Z res = lhs;
        res /= rhs;
        return res;
    }
    friend istream& operator>> (istream& is, Z& z) {
        is >> z.x;
        z.x = (z.x % P + P) % P;
        return is;
    }
    friend ostream& operator << (ostream& out,Z& z) {
        out << z.x;
        return out;
    }
};

const int N = 40010;

int w[N], cnt;
Z dp[N];

bool check(int x)
{
    string s = to_string(x);
    for (int i = 0, j = s.size() - 1; i < s.size(); i ++ , j -- ) {
        if (s[i] != s[j]) {
            return false;
        }
    }
    return true;
}

void init()
{
    for (int i = 1; i < N; i ++ ) {
        if (check(i)) {
            w[ ++ cnt] = i;
        }
    }
    dp[0] = 1;
    for (int i = 1; i <= cnt; i ++ ) {
        for (int j = w[i]; j < N; j ++ ) {
            dp[j] += dp[j - w[i]];
        }
    }
}

void solve()
{
    int n;
    cin >> n;

    cout << dp[n] << "\n";
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    init();

    int T;
    cin >> T;

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

    return 0;
}

D. Lost Arithmetic Progression(待补)

原题链接

D. Lost Arithmetic Progression

题意

输入格式

输出格式

输入样例:

8
-3 1 7
-1 2 4
-9 3 11
0 6 3
2 5 5
7 5 4
2 2 11
10 5 3
0 2 9
2 4 3
-11 4 12
1 12 2
-27 4 7
-17 8 2
-8400 420 1000000000
0 4620 10

输出样例:

0
10
-1
0
-1
21
0
273000

题解

思路

代码

#include <bits/stdc++.h>

#define int long long

using namespace std;

using i64 = long long;
constexpr int P = 1e9 + 7;

void solve()
{
    int st_b, d_b, len_b;
    int st_c, d_c, len_c;
    cin >> st_b >> d_b >> len_b >> st_c >> d_c >> len_c;

    int ed_b = st_b + d_b * (len_b - 1);
    int ed_c = st_c + d_c * (len_c - 1);

    // C在B中都出现过需要满足 范围 公差可以整除 首项之差
    if (!(st_b <= st_c && ed_c <= ed_b) || d_c % d_b != 0 || (st_c - st_b) % d_b != 0) {
        cout << "0\n";
    } else if (st_c - d_c < st_b || ed_c + d_c > ed_b) { // 若C首项的前一项或者末项的后一项不在B的范围,则说明可以无限延申
        cout << "-1\n";
    } else {
        int ans = 0;
        // d_c的因数即为d_a
        for (i64 d_a = 1; d_a * d_a <= d_c; d_a ++ ) {
            if (d_c % d_a == 0) {
                // 可以分别向左右扩展d_c/d_a个
                if (lcm(d_a, d_b) == d_c) {
                    (ans += (d_c / d_a) * (d_c / d_a)) %= P;
                }
                if (d_c / d_a != d_a && lcm(d_c / d_a, d_b) == d_c) {
                    (ans += d_a * d_a) %= P;
                }
            }
        }
        cout << ans << "\n";
    }
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int T;
    cin >> T;

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

    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值