Codeforces Round #828 (Div. 3) A~E泛做

挺有质量一套题

A.Number Replacement

对于数字串中出现次数\(\geq2\)的数字,判断是否对应同一个字母,出现次数为\(1\)的数字没有贡献。

#include <bits/stdc++.h>

using namespace std;

#define endl '\n'
#define cerr(x) std::cerr << (#x) << " is " << (x) << '\n'
#define IOS std::ios::sync_with_stdio(false);std::cin.tie(nullptr);
#define PII pair<int, int>
#define pdd pair<double,double>

#define LL long long

const double CLOCKS_PER_SECOND = ((clock_t) 1000);
const double CLOCKS_PER_MILLISECOND = ((clock_t) 1);
const int N = 2e5, M = 1e8, mod = 1e9 + 7, inf = 0x3f3f3f3f;
const double eps = 1e-6;
//#define x first
//#define y second

int T;

void solve() {
    int n, a[50 + 5], ans1 = 0, ans2;
    string s;
    cin >> n;
    map<int,char> temp;
    map<int, int> m;
    map<char, int> m2;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        m[a[i]]++;
    }
    cin >> s;
    for (int i = 0; i < s.length(); i++)
        m2[s[i]]++;

    for (int i = 1; i <= n; i++) {
        if (m[a[i]] >= 2) {
            if (temp[a[i]] == 0) {
                temp[a[i]] = s[i-1];
                continue;
            }
            if (s[i-1] != temp[a[i]]) {
                puts("NO");
                return;
            }
        }
    }
    puts("YES");
    return;
}

signed main() {
    IOS;
    cin >> T;
    while (T--) {
        solve();
    }
    return 0;
}

B.Even-Odd Increments

维护\(sum1\)\(sum2\),分别表示奇数的个数和偶数的个数。

判断每个\(x\)的奇偶性,然后讨论\(sum1\)\(sum2\)的变化即可。

#include <bits/stdc++.h>

using namespace std;

#define endl '\n'
#define cerr(x) std::cerr << (#x) << " is " << (x) << '\n'
#define IOS std::ios::sync_with_stdio(false);std::cin.tie(nullptr);
#define PII pair<int, int>
#define pdd pair<double,double>

#define LL long long

const double CLOCKS_PER_SECOND = ((clock_t) 1000);
const double CLOCKS_PER_MILLISECOND = ((clock_t) 1);
const int N = 1e5, M = 1e8, mod = 1e9 + 7, inf = 0x3f3f3f3f;
const double eps = 1e-6;
//#define x first
//#define y second

int T;


void solve() {
    int n, q;
    int a[N];
    cin >> n >> q;
    LL sum = 0;
    LL sum1 = 0, sum2 = 0;
    for (int i = 1; i <= n; i++) {
        cin >> a[i], sum += a[i];
        if (a[i] & 1) sum1++; else sum2++;
    }
    while (q--) {
        int opt;
        LL x;
        cin >> opt >> x;
        if (opt == 0) {
            if (x & 1LL) {
                sum += sum2 * x;
                sum1 = n;
                sum2 = 0;
            }//偶+奇=奇
            else {
                sum += sum2 * x;
            }//偶+偶=偶
        } else {
            if (x & 1LL) {
                sum += sum1 * x;
                sum1 = 0;
                sum2 = n;
            }//奇+奇=偶
            else {
                sum += sum1 * x;
            }//奇+偶=奇
        }
        cout << sum << endl;
    }
}

signed main() {
    IOS;
    cin >> T;
    while (T--) {
        solve();
    }
    return 0;
}

C.Traffic Light

断环为链以后就是个\(O(2n)\)的暴力。

\(string\)不知道为什么\(RE\)了,改成\(char\)才过。

#include <bits/stdc++.h>

using namespace std;

#define endl '\n'
#define cerr(x) std::cerr << (#x) << " is " << (x) << '\n'
#define IOS std::ios::sync_with_stdio(false);std::cin.tie(nullptr);
#define PII pair<int, int>
#define pdd pair<double,double>

#define LL long long

const double CLOCKS_PER_SECOND = ((clock_t) 1000);
const double CLOCKS_PER_MILLISECOND = ((clock_t) 1);
const int N = 2e5 + 10, M = 1e8, mod = 1e9 + 7, inf = 0x3f3f3f3f;
const double eps = 1e-6;
//#define x first
//#define y second

int T;


void solve() {
    int n;
    char ch;
    char s[2 * N];
    cin >> n >> ch;
    cin >> s;
    if (n == 1) {
        cout << "0" << endl;
        return;
    }
    int ans = 0;
    int temp = 0;
    for (int i = n; i <= 2 * n - 1; i++) {
        s[i] = s[i - n];
    }
    for (int i = 2 * n - 1; i >= 0; i--) {
        if (s[i] == 'g') temp = i;
        else if (s[i] == ch) ans = max(ans, temp - i);
    }
    cout << ans << endl;
    return;
}

signed main() {
    IOS;
    cin >> T;
    while (T--) {
        solve();
    }
    return 0;
}

D.Divisibility by 2^n

\(a[i]\)质因数分解,统计\(2\)的个数\(t\)。如果\(t\geq n\)那么不需要执行操作。

否则统计每个\(i\)中质因数\(2\)的个数\(m_i\),对\(i\)执行操作等价于\(t+=m_i\)

所以简单贪心一下就知道最少执行多少操作。

#include <bits/stdc++.h>

using namespace std;

#define endl '\n'
#define cerr(x) std::cerr << (#x) << " is " << (x) << '\n'
#define IOS std::ios::sync_with_stdio(false);std::cin.tie(nullptr);
#define PII pair<int, int>
#define pdd pair<double,double>

#define LL long long

const double CLOCKS_PER_SECOND = ((clock_t) 1000);
const double CLOCKS_PER_MILLISECOND = ((clock_t) 1);
const int N = 2e5 + 10, M = 1e8, mod = 1e9 + 7, inf = 0x3f3f3f3f;
const double eps = 1e-6;
//#define x first
//#define y second

int T;


void solve() {
    int n, ans = 0, res = 0;
    cin >> n;
    int a[N];
    vector<int> v;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    for (int i = 1; i <= n; i++) {
        int t = a[i], sum = 0;
        if (t & 1) continue;
        while (t % 2 == 0) t >>= 1, sum++;
        res += sum;
    }
    if (res >= n) {
        cout << 0 << endl;
        return;
    }
    for (int i = 1; i <= n; i++) {
        int t = i, sum = 0;
        if (t & 1) continue;
        while (t % 2 == 0) t >>= 1, sum++;
        v.push_back(sum);
    }
    ans = res;
    sort(v.begin(), v.end());
    reverse(v.begin(), v.end());
    for (int i = 0; i < v.size(); i++) {
        ans += v[i];
        if (ans >= n) {
            cout << i + 1 << endl;
            return;
        }
    }
    cout << -1 << endl;
    return;
}

signed main() {
    IOS;
    cin >> T;
    while (T--) {
        solve();
    }
    return 0;
}

E1. Divisible Numbers (easy version)

\(ab|xy\)等价于\(gcd(ab,xy)=ab\)。枚举\(x\),那么\(y=\frac{ab}{gcd(ab,x)}\)

\(y=d/y*y\),此时\(y\)一定小于等于\(d\)。只需要判断\(y>b\)即可。

\(O(c)\)

#include <bits/stdc++.h>

using namespace std;

#define endl '\n'
#define cerr(x) std::cerr << (#x) << " is " << (x) << '\n'
#define IOS std::ios::sync_with_stdio(false);std::cin.tie(nullptr);
#define PII pair<int, int>
#define pdd pair<double,double>

#define LL long long

const double CLOCKS_PER_SECOND = ((clock_t) 1000);
const double CLOCKS_PER_MILLISECOND = ((clock_t) 1);
const int N = 2e5 + 10, M = 1e8, mod = 1e9 + 7, inf = 0x3f3f3f3f;
const double eps = 1e-6;
//#define x first
//#define y second

int T;

LL _gcd(LL a, LL b) { return b == 0 ? a : _gcd(b, a % b); };

void solve() {
    LL a, b, c, d;
    cin >> a >> b >> c >> d;
    for (LL x = a + 1; x <= c; x++) {
        LL z = _gcd(a * b, x);
        LL y = a * b / z;
        y = d / y * y;
        if (y > b) {
            cout << x << " " << y << endl;
            return;
        }
    }
    cout << -1 << " " << -1 << endl;
    return;
}

signed main() {
    IOS;
    cin >> T;
    while (T--) {
        solve();
    }
    return 0;
}

E2.Divisible Numbers (hard version)

参考@此处

显然枚举\(x\)是不可行的。我们发现\(xy\)\(ab\)的倍数,我们尝试对\(a\)\(b\)质因数分解,\(dfs\)穷举两两的因数积。将因数之积作为\(x\),剩下的与\(E1\)一致。

一个\(longlong\)上限的数,约数数量级也仅是\(1e6\)的级别,所以对本题而言爆搜是完全可行的。

#include <bits/stdc++.h>

using namespace std;

#define endl '\n'
#define cerr(x) std::cerr << (#x) << " is " << (x) << '\n'
#define IOS std::ios::sync_with_stdio(false);std::cin.tie(nullptr);
#define PII pair<int, int>
#define pdd pair<double,double>
#define PLL pair<LL,LL>

#define LL long long

const double CLOCKS_PER_SECOND = ((clock_t) 1000);
const double CLOCKS_PER_MILLISECOND = ((clock_t) 1);
const int N = 2e5 + 10, M = 1e8, mod = 1e9 + 7, inf = 0x3f3f3f3f;
const double eps = 1e-6;
//#define x first
//#define y second

int T;
int prime[N], tot;
bool st[N];


LL _gcd(LL a, LL b) { return b == 0 ? a : _gcd(b, a % b); };

void init() {
    for (int i = 2; i < N; i++) {
        if (!st[i]) prime[tot++] = i;
        for (int j = 0; prime[j] * i < N; j++) {
            st[prime[j] * i] = 1;
            if (!(i % prime[j])) break;
        }
    }
}

void solve1(LL x, vector<PLL > &v) {//对x质因数分解
    for (int i = 0; i < tot; i++) {
        if (x % prime[i]) continue;
        int sum = 0;
        while (!(x % prime[i])) x /= prime[i], sum++;
        v.push_back({prime[i], sum});
    }
    if (x != 1) v.push_back({x, 1});
}

void dfs(int p, LL now, vector<PLL > &v, vector<LL> &v2) {
    if (p == v.size()) {
        v2.push_back(now);
        return;
    }
    LL res = 1;
    for (int i = 0; i <= v[p].second; i++) {
        dfs(p + 1, now * res, v, v2);
        if (i < v[p].second) res *= v[p].first;
    }
}

void solve() {
    LL a, b, c, d;
    vector<PLL > v;
    vector<LL> v2;
    cin >> a >> b >> c >> d;
    solve1(a, v);
    solve1(b, v);
    dfs(0, 1, v, v2);
    sort(v2.begin(), v2.end());
    for (int i = 0; i < v2.size(); i++) {
        LL x = v2[i], y = a * b / x;
        x = c / x * x, y = d / y * y;
        if (x > a && y > b) {
            cout << x << " " << y << endl;
            return;
        }
    }
    cout << -1 << " " << -1 << endl;
    return;
}

signed main() {
    IOS;
    cin >> T;
    init();
    while (T--) {
        solve();
    }
    return 0;
}
posted @ 2023-01-17 16:58  SxtoxA  阅读(26)  评论(0)    收藏  举报
12 13