Codeforces Round #603 (Div. 2)

Posted heyuhhh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #603 (Div. 2)相关的知识,希望对你有一定的参考价值。

传送门

感觉脑子还是转得太慢了QAQ,一些问题老是想得很慢。。。

A. Sweet Problem

签到。


Code

/*
 * Author:  heyuhhh
 * Created Time:  2019/11/29 22:36:19
 */
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '
'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '
'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
 
int a[3];
 
void run(){
    for(int i = 0; i < 3; i++) cin >> a[i];
    sort(a, a + 3);
    int ans = a[0];
    int d = a[2] - a[1];
    if(d >= ans) ans += a[1];
    else {
        ans += a[1] - (ans - d + 1) / 2;
    }
    cout << ans << '
';
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    int T; cin >> T;
    while(T--) run();
    return 0;
}

B. PIN Codes

注意到(n)很小,不超过(10),那么就直接暴力改变就行。
可以用一个(map)记录一下。


Code

/*
 * Author:  heyuhhh
 * Created Time:  2019/11/29 22:46:29
 */
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '
'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '
'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
 
int n;
map <string, int> mp;
string s[20];
 
void run(){
    cin >> n;
    mp.clear();
    for(int i = 1; i <= n; i++) {
        cin >> s[i];
        mp[s[i]]++;
    }
    int ans = n - mp.size();
    vector <string> res;
    for(int i = 1; i <= n; i++) {
        if(mp[s[i]] > 1) {
            string t = s[i];
            int f = 1;
            for(int j = 0; f && j < 4; j++) {
                char pre = t[j];
                for(int k = 0; k < 10; k++) {
                    t[j] = (k + '0');
                    if(mp.find(t) == mp.end()) {
                        mp[t] = 1;
                        f = 0;
                        break;   
                    }
                    if(k == 9) t[j] = pre;
                }   
            }
            res.push_back(t);
            --mp[s[i]];
        } else res.push_back(s[i]);
    }
    cout << ans << '
';
    for(auto it : res) cout << it << '
';
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    int T; cin >> T;
    while(T--) run();
    return 0;
}

C. Everyone is a Winner!

数论分块模板题。


Code

/*
 * Author:  heyuhhh
 * Created Time:  2019/11/29 22:58:21
 */
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '
'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '
'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
 
void run(){
    vector <int> ans;
    int n;
    cin >> n;
    for(int l = 1, r; l <= n; l = r + 1) {
        r = n / (n / l);
        ans.push_back(n / l);
    }
    ans.push_back(0);
    sort(all(ans));
    cout << sz(ans) << '
';
    for(auto it : ans) cout << it << ' ';
    cout << '
';
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    int T; cin >> T;
    while(T--) run();
    return 0;
}

D. Secret Passwords

题意:
现在给出(n)个长度最多为(50)的字符串,定义两个字符串等价为:

  • (A,B)等价,那么在(A,B)中至少存在一个字符相同;
  • (A,C)等价以及(B,C)等价,那么有(A,B)等价。

问最后所有的字符串可以划分为多少个等价类。

思路:
一开始以为是(bitset),后来发现是个并查集模板题= =
显然,问题中第一个描述:我们可以直接枚举每个字符,并将含有其的字符串合并在一起;对于第二个描述,显然可以发现第一步已经处理了这个问题,所有符合条件的已经自然地并在了一起。
那么并查集维护一下合并关系就行了。


Code

/*
 * Author:  heyuhhh
 * Created Time:  2019/11/29 23:09:50
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '
'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '
'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 2e5 + 5;
 
char s[N][55];
int n;
int f[N];
int find(int x) {
    return f[x] == x ? f[x] : f[x] = find(f[x]);   
}
void Union(int x, int y) {
    int fx = find(x), fy = find(y);
    if(fx != fy) {
        f[fx] = fy;
    }   
}
void run(){
    vector <int> v[26];
    for(int i = 1; i <= n; i++) {
        cin >> (s[i] + 1);
        int len = strlen(s[i] + 1);
        for(int j = 1; j <= len; j++) {
            v[s[i][j] - 'a'].push_back(i);
        }
    }
    for(int i = 1; i <= n; i++) f[i] = i;
    for(int i = 0; i < 26; i++) if(sz(v[i]) > 0) {
        int x = v[i][0];
        for(int j = 1; j < sz(v[i]); j++) {
            int y = v[i][j];
            Union(x, y);
        }   
    }
    int ans = 0;
    for(int i = 1; i <= n; i++) if(f[i] == i) ++ans;
    cout << ans << '
';
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    while(cin >> n) run();
    return 0;
}

E. Editor

题意:
现在有一个打字机,一开始当前行为空白。开始时光标位于第(1)个位置,然后输入一个字符串为执行相关的指令,指令有:

  • R:光标向右移动一个位置;
  • L:若光标大于第(1)个位置,则向左移动一个位置;
  • 其它字符:打印相关字符到当前位置,并对之前的字符进行覆盖。

每一次指令结束过后,你需要输出一个答案,该答案为:

  • 若当前串为一个合法的括号序列,那么输出括号嵌套的最大层数,比如("(sd)( ()dd)")则输出(2)
  • 否则输出(-1)

思路:
我一开始说的就是这个题,比赛的时候感觉好多东西都没想清楚...
感觉脑子转的快的话挺好想的(马后炮?)

首先来搞清楚我们要求出答案,需要满足什么关系:

  • 对于合法序列来说:要满足对于任意一个(i),有(sum[i]geq 0)。这里的(sum[i])算的是我们将(()看作(1),将())看作(-1),然后求的一个前缀和。并且还要满足(sum[n]=0),这个比较显然。
  • 那么最大层数呢?
  • 简单思考可以发现,最大层数就是要求这样一个东西(max{sum[i]},1leq ileq n)

怎么得到答案清楚了,接下来就是分析操作对答案的影响:

  • 左右移动光标:这个很简单,直接移动即可。
  • 打印字符:因为我们的(sum[i])是一个前缀的结果,那么显然我们对某一位进行修改,影响的是一个后缀,那么其实每次操作都是对一个后缀的影响。
  • 所以直接考虑线段树,每个位置表示(sum[i]),并且维护一个最小值和最大值。对于修改操作,则是在线段树上的一个区间修改;对于回答,直接找相关值就行了。

剩下的就是一点点细节。
详见代码:


Code

/*
 * Author:  heyuhhh
 * Created Time:  2019/11/30 9:57:38
 */
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '
'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '
'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e6 + 5;
 
int n;
char s[N];
int maxv[N << 2], minv[N << 2], lz[N << 2];
 
void push_up(int o) {
    minv[o] = min(minv[o << 1], minv[o << 1|1]);
    maxv[o] = max(maxv[o << 1], maxv[o << 1|1]);
}
 
void push_down(int o, int l, int r) {
    if(lz[o] != 0) {
        int mid = (l + r) >> 1;
        maxv[o << 1] += lz[o];
        minv[o << 1] += lz[o];
        maxv[o << 1|1] += lz[o];
        minv[o << 1|1] += lz[o];
        lz[o << 1] += lz[o];
        lz[o << 1|1] += lz[o];
        lz[o] = 0;
    }
}
 
void build(int o, int l, int r) {
    maxv[o] = minv[o] = 0;   
    if(l == r) return;
    int mid = (l + r) >> 1;
    if(l <= mid) build(o << 1, l, mid);
    if(r > mid) build(o << 1|1, mid + 1, r);
}
 
void upd(int o, int l, int r, int L, int R, int v) {
    if(L <= l && r <= R) {
        lz[o] += v;
        maxv[o] += v; minv[o] += v;
        return;
    }   
    push_down(o, l, r);
    int mid = (l + r) >> 1;
    if(L <= mid) upd(o << 1, l, mid, L, R, v);
    if(R > mid) upd(o << 1|1, mid + 1, r, L, R, v);
    push_up(o);
}
 
int a[N];
 
void run(){
    cin >> (s + 1);
    build(1, 1, n);
    int p = 1;
    int sum = 0;
    for(int i = 1; i <= n; i++) {
        if(s[i] == '(') {
            if(a[p] == 0) upd(1, 1, n, p, n, 1), ++sum;
            else if(a[p] == -1) {
                upd(1, 1, n, p, n, 2), sum += 2;
            }
            a[p] = 1;
        } else if(s[i] == ')') {
            if(a[p] == 0) upd(1, 1, n, p, n, -1), --sum;
            else if(a[p] == 1) {
                upd(1, 1, n, p, n, -2), sum -= 2;   
            }
            a[p] = -1;
        } else if(s[i] == 'R') {
            ++p;
        } else if(s[i] == 'L') {
            if(p > 1) --p;
        } else {
            if(a[p] == 1) upd(1, 1, n, p, n, -1), --sum;
            else if(a[p] == -1) upd(1, 1, n, p, n, 1), ++sum;
            a[p] = 0;
        }   
        if(sum == 0 && minv[1] >= 0) {
            cout << maxv[1];   
        } else cout << -1;
        cout << " 
"[i == n];
    }
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    while(cin >> n) run();
    return 0;
}

以上是关于Codeforces Round #603 (Div. 2)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #603 (Div. 2)

Codeforces Round #603 (Div. 2) E. Editor 线段树

Codeforces Round #603 (Div. 2) A. Sweet Problem(数学)

Codeforces Round #603 (Div. 2) B. PIN Codes

Codeforces Round #603 (Div. 2)

Codeforces Round #603 (Div. 2) F. Economic Difficulties dp