Codeforces Round #799 (Div. 4) A-H

Codeforces Round #799 (Div. 4)

https://codeforces.com/contest/1692
我心痛死了。。。昨天卡在E题,然后没往下做,结果今天补题的时候发现G题贼简单TAT我哭死!!

A. Marathon

统计b c d 中有多少个比 a 大的

#include <bits/stdc++.h>

using namespace std;

void solve () {
    int a, b, c, d;
    int cnt = 0;
    cin >> a >> b >> c >> d;
    if (b > a)
        cnt ++;
    if (c > a)
        cnt ++;
    if (d > a)
        cnt ++;
    cout << cnt << endl;
}

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

B. All Distinct

每次删掉两个数字,留下的数列当中不能有相同的数字,求留下的最大长度。
实现:统计有多少种数字,记为m,然后看总数n-m是否为偶数;是的话m就是答案,否则要多删除一个

#include <bits/stdc++.h>

using namespace std;

void solve () {
    int n;
    cin >> n;
    vector <int> v (n + 1);
    for (int i = 0; i < n; i ++)
        cin >> v[i];
    sort (v.begin (), v.end ());
    // for (auto i : v)
    //     cout << i << ' ';
    // cout << endl;
    v.erase (unique (v.begin(), v.end ()), v.end());
    // for (auto i : v)
    //     cout << i << ' ';
    // cout << endl;
    int m = v.size () - 1;
    if ((n - m) & 1)  
        cout << max (0, m - 1) << endl;
    else
        cout << m << endl;
}

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

C. Where's the Bishop?

据观察不难发现,只需找出
的形状即可

#include <bits/stdc++.h>

using namespace std;

void solve () {
    char a[9][9];
    for (int i = 1; i <= 8; i ++)
        for (int j = 1; j <= 8; j ++)
            cin >> a[i][j];

    for (int i = 1; i <= 7; i ++)
        for (int j = 1; j <= 7; j ++)
        if (a[i][j] == '#' && a[i-1][j-1] == '#' && a[i-1][j+1] == '#' && a[i+1][j-1] == '#' && a[i+1][j+1] == '#') {
            cout << i << ' ' << j << endl;
            break;
        }
}

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

D. The Clock

非常像学校OJ题的一道模拟
注意分到了60会进位!!这里调了半天xs

#include <bits/stdc++.h>

using namespace std;

bool check (int x, int y) {
    string s1, s2;
    if (x < 10) s1 = '0' + to_string (x);
    else    s1 = to_string (x);
    if (y < 10) s2 = '0' + to_string (y);
    else    s2 = to_string (y);

    reverse (s2.begin (), s2.end());
    if (s1 == s2)
        return true;
    return false;
}

void solve () {
    string s;
    int x;
    cin >> s >> x;

    int dh = x / 60, dm = x % 60;
    int sh = (s[0] - '0') * 10 + (s[1] - '0');
    int sm = (s[3] - '0') * 10 + (s[4] - '0');
    int cnt = check (sh, sm) ? 1 : 0;

    if (x == 1440) {
        cout << cnt << endl;
        return ;
    }

    int hh = sh, mm = sm;
    do  {
        //cout << hh << ' ' << mm << endl;
        hh = hh + dh, mm = dm + mm;
        if (mm >= 60)   hh += (mm / 60), mm %= 60;
        hh %= 24;
        if (hh == sh && mm == sm)
            break;
        if (check (hh, mm)) cnt ++;// cout << hh << ' ' << mm << endl;;
        
    } while (1);
    cout << cnt << endl;
}

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

E. Binary Deque

我处理的很复杂。。其实就是简单的扫一遍双指针记录最小答案(因为div4都是很暴力的)

#include <bits/stdc++.h>

using namespace std;
typedef pair<int, int> pii;
const int N = 2e5 + 5;
int a[N];

void solve () {
    int n, s, sum = 0;
    cin >> n >> s;
    for (int i = 1; i <= n; i ++)
        cin >> a[i], sum += a[i];
    if (sum == s) {
        cout << 0 << endl;
    }
    else if (sum < s) {
        cout << -1 << endl;
    }
    else {
        int ans = 2e5 + 5, sum = 0;
        for (int i = 1, j = 1; i < n; i ++) {
            while (j <= n && sum + a[j] <= s) {
                sum += a[j ++];
            }
            ans = min (ans, i + n - j);
            sum -= a[i]; //有点类似回溯的思想
        }
        cout << ans << endl;
    }
    
}

int main () {
    int t;
    cin >> t;
    while (t --)
        solve ();
}
//统计边缘的1
//统计1的代价
//双指针
//我不会写双指针。。泪目

F. 3SUM

直接鼓励大胆的暴力
出现三次以上的不考虑

#include <bits/stdc++.h>

using namespace std;

void solve () {
    vector <int> v;
    int n;
    cin >> n;
    int cnt[10] = {};
    for (int i = 0; i < n; i ++) {
        int x;
        cin >> x;
        x %= 10;
        if (cnt[x] < 3) {
            v.push_back (x);
            cnt[x] ++;
        } 
    }
    sort (v.begin (), v.end ());
    n = v.size ();
    // for (auto i : v)
    //     cout << i << ' ';
    // cout << endl;

    for (int i = 0; i < n; i ++)
        for (int j = i + 1; j < n; j ++)
            for (int k = j + 1; k < n; k ++) 
                if ((v[i] + v[j] + v[k]) % 10 == 3) {
                    cout << "YES\n";
                    return ;
                }
    cout << "NO\n";   

}

int main () {
    int t;
    cin >> t;
    while (t --) {
        solve ();
    }
}
//暴力枚举所有选取三个数的可能
//稍微优化:出现次数超过三次的就不管

G. 2^Sort

就看 区间内 每一个两倍的后一项是否大于前一项

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

using namespace std;
const int N = 2e5 + 5;
int a[N];

void solve () {
    int n, k, cnt = 0;
    cin >> n >> k;
    for (int i = 1; i <= n; i ++)
        cin >> a[i];
    int len = 0;

    for (int i = n; i > 1; i --) {
        if (a[i] * 2 > a[i - 1])
            len ++;
        else
            len = 0;
        if (len == k)
            cnt ++, len --;
        
    }
    cout << cnt << endl;

}

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


//区间内 每一个两倍的后一项是否大于前一项
//倒着看

H. Gambling

求最大子段和。
因为我不会,所以参考了jls的代码。苯人看了好久才懂的,所以放上一些潦草的笔记辅助像我一样的菜鸡来理解:



我觉得自己手动模拟一遍就很好理解了

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

using namespace std;

void solve () {
    int n;
    cin >> n;
    map<int, vector <int>> p; //值 下标
    vector<int> x(n);

    for (int i = 0; i < n; i ++) {
        cin >> x[i];
        p[x[i]].push_back (i); //记录同一数字的下标
    }

    int a = x[0], l = 0, r = 1, ans = 1;

    for (auto i : p) {
        auto q = i.second;//下标列表
        int val = 0, st = q[0]; //区间贡献 起点
        for (int j = 0; j < q.size (); j ++) {
            int ed = q[j];
            int cur = j - (ed - j);//统计该区间的贡献值
            if (cur < val) val = cur, st = ed; //该行的作用在于,如果出现负值就说明前面段的选取不是最优的,要舍弃,跳过去
    
            int res = cur + 1 - val;
            //记录答案
            if (res > ans) {
                ans = res;
                a = i.first, l = st, r = ed + 1;
            }
        }
    }
    cout << a << ' ' << l + 1 << ' ' << r << endl;
}

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

}
posted @ 2022-06-15 08:27  Sakana~  阅读(252)  评论(2编辑  收藏  举报