Codeforces Round 690 (Div. 3)

Codeforces Round 690 (Div. 3)

https://codeforces.com/contest/1462

A. Favorite Sequence

按题意输出

#include <bits/stdc++.h>

using namespace std;
const int N = 1e5 + 5;
int a[N], n;

void solve () {
    cin >> n;
    for (int i = 1; i <= n; i++)    cin >> a[i];
    for (int i = 0; i < n / 2; i++) {
        cout << a[i + 1] << ' ';
        if (i + 1 != n - i) cout << a[n - i] << ' ';
    }
    if (n & 1)  cout << a[n / 2 + 1];
    cout << endl;
}

int main () {
    int t;
    cin >> t;
    while (t--)     solve ();
}

B. Last Year's Substring

形如:

...2020
2...020
20...20
202...0
2020...

分类讨论即可

#include <bits/stdc++.h>

using namespace std;

void solve () {
    int n;
    string s;
    cin >> n >> s;
    if (s[0] == '2' && s[n-3] == '0' && s[n-2] == '2' && s[n-1] == '0') cout << "YES\n";
    else if (s[0] == '2' && s[1] == '0' && s[n-2] == '2' && s[n-1] == '0') cout << "YES\n";
    else if (s[0] == '2' && s[1] == '0' && s[2] == '2' && s[n-1] == '0') cout << "YES\n";
    else if (s[n-4] == '2' && s[n-3] == '0' && s[n-2] == '2' && s[n-1] == '0') cout << "YES\n";
    else if (s[0] == '2' && s[1] == '0' && s[2] == '2' && s[3] == '0') cout << "YES\n";
    else    cout << "NO\n";
}

int main () {
    int t;
    cin >> t;
    while (t--)     solve ();
}

C. Unique Number

构造形如 123456789
易发现最达能构造出来的数字就是45,模拟即可,倒着从9开始填

#include <bits/stdc++.h>

using namespace std;

void solve () {
    int n;
    cin >> n;
    //cout << n << ": ";
    if (n < 10)     cout << n << endl;
    else if (n > 45)    cout << "-1\n";
    else {
        vector<int> v;
        for (int i = 9; i > 0; i--) {
            int t = min (i, n);
            //cout << t << ' ';
            if (v.size () && v.back () == t)    v.push_back (t - 1), v.push_back (1);
            else    v.push_back (t);
            n -= t;
            if (n == 0) break;
        }
        reverse (v.begin (), v.end ());
        
        for (auto i : v)    cout << i;
        cout << endl;
    }
}

int main () {
    int t;
    cin >> t;
    while (t--)     solve ();
}

D. Add to Neighbour and Remove

和固定,直接枚举最终局面,贪心计算和判断是否合法。

#include <bits/stdc++.h>

using namespace std;
const int N = 3005;
int a[N], n;

void solve () {
    int sum = 0;
    cin >> n;
    for (int i = 1; i <= n; i++)    cin >> a[i], sum += a[i];
    for (int len = n; len >= 1; len--) {
        //剩下len个数
        if (sum % len)  continue;
        int tt = sum / len, cur = 0, cnt = 0;
        bool suc = true;
        for (int i = 1; i <= n; i++) {
            cur += a[i];
            if (cur == tt)  cnt++, cur = 0;
            else if (cur > tt) {
                suc = false;
                break;
            }
        }
        if (suc) {
            cout << n - len << endl;
            break;
        }
    }    
}

int main () {
    int t;
    cin >> t;
    while (t--)     solve ();
}

E1. Close Tuples (easy version)

见下表:

x  x+1  x+2
3  0    0
2  1    0
2  0    1
1  2    0
1  0    2
1  1    1

枚举然后计算次数即可

#include <bits/stdc++.h>
#define ll long long

using namespace std;
const int N = 2e5 + 5;
ll n, x, a[N];

void solve () {
    ll ans = 0;
    cin >> n;
    for (int i = 1; i <= n + 3; i++)    a[i] = 0;
    for (int i = 1; i <= n; i++)    cin >> x, a[x]++;
    for (int i = 1; i <= n; i++) {
        ll t = a[i], tt = a[i + 1], ttt = a[i + 2];
        if (t >= 3)     ans += (t * (t - 1) * (t - 2)) / 6;
        if (tt > 0)     ans += (t * (t - 1) / 2) * tt;
        if (tt > 1)     ans += t * (tt * (tt - 1) / 2);
        if (ttt > 0)    ans += t * tt * ttt + (t * (t - 1) / 2) * ttt;
        if (ttt > 1)    ans += t * (ttt * (ttt - 1) / 2);
    }
    cout << ans << endl;
}

int main () {
    int t;
    cin >> t;
    while (t--)     solve ();
}
#include <bits/stdc++.h>
#define ll long long

using namespace std;
const int N = 2e5 + 5;
ll n, x, a[N];

void solve () {
    ll ans = 0;
    cin >> n;
    for (int i = 1; i <= n; i++)    cin >> a[i];
    sort (a + 1, a + n + 1);
    for (int i = 1; i <= n; i++) {
        int pos = upper_bound (a + 1, a + n + 1, a[i] + 2) - a;
        if (pos - i >= 3) {
            ll len = pos - i - 1;
            ans += len * (len - 1) / 2;
        }
    }
    cout << ans << endl;
}

int main () {
    int t;
    cin >> t;
    while (t--)     solve ();
}

E2. Close Tuples (hard version)

相当于在 \([a_i, a_i+k]\) 范围的若干个数中选 \(m\) 个数的组合。

#include <bits/stdc++.h>
#define ll long long

using namespace std;
const int N = 2e5 + 5, mod = 1e9 + 7;
ll n, m, k, a[N];

ll fact[N], infact[N];

ll qmi(ll a, ll k, ll p){
    ll res = 1;
    while(k){
        if(k & 1)
            res = (ll)res * a % p;
        a = (ll)a * a % p;
        k >>= 1;
    }
    return res;
}

ll C (int a, int b) {
    if (a < b)  return 0;
    return fact[a] * infact[b] % mod * infact[a - b] % mod;
}

void init () {
    fact[0] = infact[0] = 1;
    for(int i = 1; i < N; i++){
        fact[i] = (ll)fact[i-1] * i % mod;
        infact[i] = (ll)infact[i-1] * qmi(i, mod - 2,mod) % mod;
    }
}

void solve () {
    ll ans = 0;
    cin >> n >> m >> k;
    for (int i = 1; i <= n; i++)    cin >> a[i];
    sort (a + 1, a + n + 1);
    for (int i = 1; i <= n; i++) {
        int pos = upper_bound (a + 1, a + n + 1, a[i] + k) - a;
        if (pos - i >= m) { //[ai, ai+k] 的范围内共 pos-i-1 个数中选
            (ans += C (pos - i - 1, m - 1)) %= mod;
        }
    }
    cout << ans << endl;
}

int main () {
    init ();
    int t;
    cin >> t;
    while (t--)     solve ();
}

F. The Treasure of The Segments

计算每个区间的香蕉区间数,记录最大值。
具体计算:总区间数 - 相离区间数
相离:大于当前右端点的左端点数 + 大于当前左端点的右端点数
二分查找

#include <bits/stdc++.h>

using namespace std;
const int N = 2e5 + 5;
int n;

struct Node {
    int l, r;
    bool operator<(const Node &t) const {
        if (l != t.l)   return l < t.l;
        return r < t.r;
    }
}p[N];

void solve () {
    int ans = 1;
    cin >> n;
    vector<int> vl, vr;
    for (int i = 1; i <= n; i++) {
        cin >> p[i].l >> p[i].r;
        vl.push_back (p[i].l);
        vr.push_back (p[i].r);
    }

    sort (vl.begin (), vl.end ()), sort (vr.begin (), vr.end ());
    for (int i = 1; i <= n; i++) {
        int cnt = 1, l = p[i].l, r = p[i].r;
        //找不相交的有多少个
        int rr = upper_bound (vl.begin (), vl.end (), r) - vl.begin (); //在右侧不相交
        rr = n - rr;
        int ll = lower_bound (vr.begin (), vr.end (), l) - vr.begin (); //再左侧不相交
        cnt = n - ll - rr;
        ans = max (ans, cnt);
    }
    cout << n - ans << endl;
}

int main () {
    int t;
    cin >> t;
    while (t--)     solve ();
}
posted @ 2023-08-06 17:30  Sakana~  阅读(10)  评论(0编辑  收藏  举报