Educational Codeforces Round 90 (Rated for Div. 2)

传送门

A. Donut Shops

贪心考虑即可。

Code
/*
 * Author:  heyuhhh
 * Created Time:  2020/6/25 22:38:09
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#include <functional>
#include <numeric>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#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 << std::endl; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
  template <template<typename...> class T, typename t, typename... A> 
  void err(const T <t> &arg, const A&... args) {
  for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
  #define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
 
void run() {
    ll a, b, c; 
    cin >> a >> b >> c;
    if (a < c) {
        cout << 1 << ' ';
    } else {
        cout << -1 << ' ';
    }
    if (a * b <= c) {
        cout << -1 << '\n';
    } else {
        cout << b << '\n';
    }
}
 
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. 01 Game

贪心找出有多少对\(01,10\)即可。
因为假设现在为\(010\),删掉\(01\)或者删掉\(10\),不影响之后的操作,都会剩下一个\(0\)

Code
/*
 * Author:  heyuhhh
 * Created Time:  2020/6/25 22:43:59
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#include <functional>
#include <numeric>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#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 << std::endl; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
  template <template<typename...> class T, typename t, typename... A> 
  void err(const T <t> &arg, const A&... args) {
  for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
  #define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
 
void run() {
    string s; cin >> s;
    int n = s.length();
    int cnt0 = 0, cnt1 = 0;
    for (int i = 0; i < n; i++) {
        if (s[i] == '0') ++cnt0;
        else ++cnt1;
    }
    if (cnt0 == n || cnt1 == n) {
        cout << "NET" << '\n';
        return;
    }
    int cnt = 0;
    vector <int> sta;
    for (int i = 0; i < n; i++) {
        if (sz(sta) == 0) {
            sta.push_back(s[i] - '0');
        } else {
            if (sta.back() != s[i] - '0') {
                sta.pop_back();
                ++cnt;
            } else {
                sta.push_back(s[i] - '0');
            }
        }
    }
    if (cnt & 1) {
        cout << "DA" << '\n';
    } else {
        cout << "NET" << '\n';
    }
}
 
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. Pluses and Minuses

贪心考虑,维护每个值出现的第一个位置即可。
因为\(|s|\)的长度不会超过\(10^6\),故直接按照程序来进行枚举就行。
详见代码:

Code
/*
 * Author:  heyuhhh
 * Created Time:  2020/6/25 22:54:16
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#include <functional>
#include <numeric>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#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 << std::endl; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
  template <template<typename...> class T, typename t, typename... A> 
  void err(const T <t> &arg, const A&... args) {
  for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
  #define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
 
void run() {
    string s; cin >> s;
    int n = s.length();
    map <int, int> mp;
    int sum = 0, Min = INF;
    for (int i = 0; i < n; i++) {
        if (s[i] == '-') --sum;
        else ++sum;
        Min = min(Min, sum);
        if (mp.find(sum) == mp.end()) {
            mp[sum] = i + 1;
        }
    }
    ll ans = 0;
    for (int i = 0; i < n; i++) {
        if (mp.find(-(i + 1)) != mp.end()) {
            ans += mp[-(i + 1)];
        } else break;
    }
    ans += n;
    cout << ans << '\n';
}
 
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. Maximum Sum on Even Positions

先将所有偶数位置的数选进来,之后每个奇数的贡献为\(a_i-a_{i+1}\)或者\(a_i-a_{i-1}\)
那么之后找一个最大连续子段和即可,可以直接\(O(n)dp\)

Code
/*
 * Author:  heyuhhh
 * Created Time:  2020/6/25 23:02:08
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#include <functional>
#include <numeric>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#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 << std::endl; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
  template <template<typename...> class T, typename t, typename... A> 
  void err(const T <t> &arg, const A&... args) {
  for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
  #define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
 
void run() {
    int n; cin >> n;
    vector <int> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    ll ans = 0;
    for (int i = 0; i < n; i += 2) {
        ans += a[i];
    }
    vector <int> b;
    for (int i = 0; i < n; i += 2) {
        if (i + 1 < n) {
            b.push_back(-a[i] + a[i + 1]);
        }
    }
    vector <int> c;
    for (int i = 0; i < n; i += 2) {
        if (i - 1 >= 0) {
            c.push_back(-a[i] + a[i - 1]);
        }
    }
    auto gao = [&] (vector <int>& v) {
        int sz = sz(v);
        if (sz == 0) return 0ll;
        vector <ll> dp(sz);
        dp[0] = max(0, v[0]);
        for (int i = 1; i < sz(v); i++) {
            if (dp[i - 1] > 0) {
                dp[i] = dp[i - 1] + v[i];
            } else {
                dp[i] = v[i];
            }
        }
        return *max_element(all(dp));
    };
    ll res = max(gao(b), gao(c));
    ans += res;
    cout << ans << '\n';
}
 
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;
}

E. Sum of Digits

题意:
定义\(f(x)\)\(x\)的各个位置上的数字之和。
给定\(n,k,n\leq 150,k\leq 9\),找到最小的\(x\),使得:

\[f(x)+f(x+1)+\cdots+f(x+k)=n \]

思路:
较难处理的点为进位的情况,但我们容易发现几个关键点:

  • 最多进位一次;
  • 与前面的\(9\)的个数有关。

所以枚举最后一位\(r\)以及前面\(9\)的个数\(c9\)\(k\)很小就直接枚举即可,这样就能方便处理进位对答案的贡献。
前面的一些贪心填即可,模式为\(x99..98\underbrace{999}_{c9}r\)
因为\(x\)最小,首先让其长度最小,那么后面尽可能大即可。

Code
/*
 * Author:  heyuhhh
 * Created Time:  2020/6/26 9:16:53
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#include <functional>
#include <numeric>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#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 << std::endl; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
  template <template<typename...> class T, typename t, typename... A> 
  void err(const T <t> &arg, const A&... args) {
  for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
  #define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
 
ll calc(int n, int k, int c9, int r) {
    int res = 0;
    for (int i = 0; i <= k; i++) {
        if (i + r < 10) {
            res += i + r + 9 * c9;
        } else {
            res += i + r - 9;
        }
    }
    int need = n - res;
    if (need % (k + 1) || need < 0) {
        return 1e18;
    }
    need /= k + 1;
    ll ans = 0;
    if (need < 9) {
        ans = need;
    } else {
        need -= 8;
        int t = need % 9;
        ans = t;
        for (int i = 1; i <= need / 9; i++) {
            ans = ans * 10 + 9;
        }
        ans = ans * 10 + 8;
    }
    for (int i = 1; i <= c9; i++) {
        ans = ans * 10 + 9;
    }
    ans = ans * 10 + r;
    return ans;
}
 
void run() {
    int n, k; cin >> n >> k;
    ll ans = 1e18;
    for (int c9 = 0; c9 <= 16; c9++) {
        for (int r = 0; r < 10; r++) {
            ans = min(ans, calc(n, k, c9, r));
        }
    }
    if (ans == 1e18) ans = -1;
    cout << ans << '\n';
}
 
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;
}

F. Network Coverage

题意:
给定一个长度为\(n\)的环,每个位置需要\(a_i\)个物品,现在有序列\(b_i\),表示共有\(b_i\)个物资分配给\(a_i,a_{i+1}\)
问是否能使得所有位置都得到至少\(a_i\)个物品。

思路:
考虑暴力做法:

  • 枚举\(b_n\)分配多少个给\(1\),那么之后贪心扫一遍看看每一个是否满足,并且check一下最后留下的是否能满足枚举的分配的。

因为\(a_i,b_i\leq 10^9\),所以直接枚举显然不行。
注意到枚举的\(x\)是具有单调性的,如果枚举的\(x\)较小,不够那么显然\(x\)越大越好。但是这里有个问题,因为最后还需要check一下剩下的是否不小于\(x\),那么\(x\)大了的话有些可能会被浪费不存在解。也就是说\(x\)在一个范围内是可行的,最左或者最右都不是很行。所以可以直接三分找最小的\(x\)
当然也可以二分,因为函数值只有\(0,1\),两端为\(0\),中间为\(1\)。并且两端\(0\)的判断条件不相同,所以可以直接根据这个性质来进行二分。
详见代码:

Code
/*
 * Author:  heyuhhh
 * Created Time:  2020/6/25 23:42:09
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#include <assert.h>
#include <functional>
#include <numeric>
#define MP make_pair
#define fi first
#define se second
#define pb push_back
#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 << std::endl; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
  template <template<typename...> class T, typename t, typename... A> 
  void err(const T <t> &arg, const A&... args) {
  for (auto &v : arg) std::cout << v << ' '; err(args...); }
#else
  #define dbg(...)
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
 
void run() {
    int n; cin >> n;
    vector <int> a(n), b(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    for (int i = 0; i < n; i++) {
        cin >> b[i];
    }
    auto check = [&] (ll x) {
        ll t = x;
        for (int i = 0; i < n; i++) {
            x += b[i] - a[i];
            x = min(x, (ll)b[i]);
            if (x < 0) return 1;
        }
        if (x >= t) return 0;
        return 2;
    };
    int l = 0, r = b[n - 1] + 1, mid;
    while (l < r) {
        mid = (l + r) >> 1;
        int op = check(mid);
        if (op == 1) l = mid + 1;
        else if (op == 2) r = mid;
        else {
            cout << "YES" << '\n';
            return;
        }
    }
    cout << "NO" << '\n';
}
 
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;
}
posted @ 2020-06-26 10:50  heyuhhh  阅读(425)  评论(1编辑  收藏  举报