Codeforces Round #617 (Div. 3)

传送门

A. Array with Odd Sum

签到。

Code
/*
 * Author:  heyuhhh
 * Created Time:  2020/2/4 22:36:18
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#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 = 2000 + 5;
 
int n;
int a[N];
 
void run(){
    int cnt = 0;
    cin >> n;
    for(int i = 1; i <= n; i++) {
        cin >> a[i];
        if(a[i] & 1) ++cnt;
    }
    if(cnt == 0) cout << "NO" << '
';
    else {
        if(cnt % 2 == 0 && n == cnt) cout << "NO" << '
';
        else cout << "YES" << '
';   
    }
}
 
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. Food Buying

贪心即可。

Code
/*
 * Author:  heyuhhh
 * Created Time:  2020/2/4 22:41:54
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#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(){
    int n; cin >> n;
    ll ans = 0;
    while(n) {
        int t = n / 10 * 10;
        if(t == 0) t = n;
        ans += t;
        n = n - t + n / 10;
    }
    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;
}

C. Yet Another Walking Robot

用个(map)记录一下走到某一坐标的最晚时刻,然后直接维护答案就行。

Code
/*
 * Author:  heyuhhh
 * Created Time:  2020/2/4 22:48:22
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#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;
 
int n;
char s[N];
 
void run(){
    cin >> n >> (s + 1);
    map <int, map<int, int>> mp;
    int x = 0, y = 0;
    mp[x][y] = 0;
    int ans = INF, l, r;
    for(int i = 1; i <= n; i++) {
        if(s[i] == 'L') --x;
        if(s[i] == 'R') ++x;
        if(s[i] == 'U') ++y;
        if(s[i] == 'D') --y;
        if(mp[x].find(y) == mp[x].end()) {
            mp[x][y] = i;   
        } else {
            if(i - mp[x][y] < ans) {
                ans = i - mp[x][y];
                l = mp[x][y] + 1, r = i;   
            }
            mp[x][y] = i;
        }
    }
    if(ans == INF) cout << -1 << '
';
    else cout << l << ' ' << r << '
';
}
 
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. Fight with Monsters

因为每次先手都是固定的,相当于打每只怪兽都是独立的。所以直接贪心即可。

Code
/*
 * Author:  heyuhhh
 * Created Time:  2020/2/4 22:59:21
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#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;
 
int n, a, b, k;
int h[N];
 
void run(){
    int ans = 0;
    vector <int> v;
    for(int i = 1; i <= n; i++) {
        cin >> h[i];
        int r = (h[i] - 1) % (a + b) + 1;
        if(r <= a) {
            ++ans;
        } else {
            int need = (r - 1) / a;
            v.push_back(need);
        }
    }
    sort(all(v));
    for(auto it : v) {
        if(k >= it) k -= it, ++ans;   
    }
    cout << ans << '
';
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    while(cin >> n >> a >> b >> k) run();
    return 0;
}

E1. String Coloring (easy version)

题意:
给出一个字符串,现在给每个位置进行染色,至多用两种颜色。
然后可以执行任意次操作:交换两个相邻的且颜色不相同的字符。
问执行任意次操作后,得到的字符串是否能有序,如果能,给出一种染色方案。

思路:
显然每个字符只会和其前面比他大的字符有关,那么直接暴力枚举,根据前面的颜色来确定当前的颜色就行。

Code
/*
 * Author:  heyuhhh
 * Created Time:  2020/2/4 23:23:04
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#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 = 200 + 5;
 
int n;
char s[N];
int c[N];
 
void run(){
    memset(c, 0, sizeof(c));
    cin >> (s + 1);
    for(int i = 1; i <= n; i++) {
        int cnt = 0;
        for(int j = 1; j < i; j++) {
            if(s[j] > s[i]) {
                if(c[i] == c[j]) {
                    c[i] = c[j] ^ 1;
                    ++cnt;   
                }
            }
        }
        if(cnt > 1) {
            cout << "NO" << '
';   
            return;
        }
        c[i] = cnt;
    }
    cout << "YES" << '
';
    for(int i = 1; i <= n; i++) cout << c[i];
    cout << '
';
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    while(cin >> n) run();
    return 0;
}

E2. String Coloring (hard version)

题意:
题意大致和E1相同,只是现在可以染多种颜色,求最终最少染了多少种颜色,并给出一种染色方案。

思路:
显然每个字符只会和其前面比它大的字符有关。
暴力的想法就是枚举每个比它大的字符,最后对每个字符的取值取并然后求mex。
注意到如果有多个字符都等于相同的颜色,显然越大的字符越有用。那么我们对(1)~(n)中的每个数维护“当前颜色与之相等且最大的字符”。
那么我们最终求的就是第一个取值小于等于当前字符的位置。
可以用权值线段树等乱七八糟的东西来维护。

Code
/*
 * Author:  heyuhhh
 * Created Time:  2020/2/4 23:48:52
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#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;
 
int n;
char s[N];
int c[N];
 
int minv[N << 2];
int query(int o, int l, int r, int v) {
    if(l == r) return l;
    int mid = (l + r) >> 1;
    if(minv[o << 1] <= v) return query(o << 1, l, mid, v);
    return query(o << 1|1, mid + 1, r, v);
}
void update(int o, int l, int r, int p, int v) {
    if(l == r) {
        minv[o] = max(v, minv[o]);
        return;
    }   
    int mid = (l + r) >> 1;
    if(p <= mid) update(o << 1, l, mid, p, v);
    else update(o << 1|1, mid + 1, r, p, v);
    minv[o] = min(minv[o << 1], minv[o << 1|1]);
}
void run(){
    cin >> (s + 1);
    for(int i = 1; i <= n; i++) {
        int p = query(1, 1, n, s[i] - 'a');
        c[i] = p;
        update(1, 1, n, p, s[i] - 'a');
    }
    int Max = *max_element(c + 1, c + n + 1);
    cout << Max << '
';
    for(int i = 1; i <= n; i++) cout << c[i] << ' ';
    cout << '
';
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    while(cin >> n) run();
    return 0;
}

F. Berland Beauty

题意:
给出一颗(n,nleq 5000)个结点的无向树,其树边上有权值范围为([1,10^6]),但现在不知道这些权值。
同时给出(m)条信息,每个信息为(a_i,b_i,c_i),即树上(a_i)(b_i)的路径中最小权值为多少。
现在就要通过这些信息构造出一种合法的权值序列,如果出现不合法的情况输出(-1)

思路:
对于每个信息,直接暴力给路径上的每条边打标记,若一条树边的权值为(x),意味着这条边权值最小为(x)
处理完所有信息后再检验一次看是否合法,若不合法则说明出现矛盾,合法的话直接输出即可。
注意没处理到的边要随便赋一个值。

Code
/*
 * Author:  heyuhhh
 * Created Time:  2020/2/5 0:09:26
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#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 = 5000 + 5;
 
int n, m;
vector <int> G[N];
int deep[N], fa[N];
int f[N], e[N][N], id[N][N];
int a[N], b[N], c[N];
 
void dfs(int u, int p) {
    deep[u] = deep[p] + 1;
    fa[u] = p;
    for(auto v : G[u]) {
        if(v != p) dfs(v, u);
    }
}
void dfs2(int u, int p) {
    for(auto v : G[u]) {
        if(v != p) {
            dfs2(v, u);
            f[id[u][v]] = e[u][v];   
        }
    }   
}
void run(){
    for(int i = 1; i < n; i++) {
        int u, v; cin >> u >> v;
        G[u].push_back(v);
        G[v].push_back(u);
        id[u][v] = id[v][u] = i;
    }
    dfs(1, 0);
    cin >> m;
    for(int i = 1; i <= m; i++) cin >> a[i] >> b[i] >> c[i];
    for(int i = 1; i <= m; i++) {
        if(deep[a[i]] < deep[b[i]]) swap(a[i], b[i]);
        int k1 = a[i], k2 = b[i], g = c[i];
        while(deep[k1] != deep[k2]) {
            int to = fa[k1];
            if(e[to][k1] <= g) e[to][k1] = e[k1][to] = g;
            k1 = to;
        }   
        while(k1 != k2) {
            int to1 = fa[k1], to2 = fa[k2];
            if(e[to1][k1] <= g) e[to1][k1] = e[k1][to1] = g;
            if(e[to2][k2] <= g) e[to2][k2] = e[k2][to2] = g;   
            k1 = to1, k2 = to2;
        }
    }
    for(int i = 1; i <= m; i++) {
        if(deep[a[i]] < deep[b[i]]) swap(a[i], b[i]);
        int k1 = a[i], k2 = b[i], g = c[i];
        int Min = INF;
        while(deep[k1] != deep[k2]) {
            int to = fa[k1];
            Min = min(Min, e[to][k1]);
            k1 = to;
        }   
        while(k1 != k2) {
            int to1 = fa[k1], to2 = fa[k2];
            Min = min(Min, min(e[to1][k1], e[to2][k2]));
            k1 = to1, k2 = to2;
        }       
        if(Min != g) {
            cout << -1 << '
';
            return;   
        }
    }
    dfs2(1, 0);
    for(int i = 1; i < n; i++) if(!f[i]) f[i] = 1000000;
    for(int i = 1; i < n; i++) cout << f[i] << ' ';
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    while(cin >> n) run();
    return 0;
}
原文地址:https://www.cnblogs.com/heyuhhh/p/12262877.html