【cf比赛记录】Codeforces Round #600 (Div. 2)

Codeforces Round #600 (Div. 2) ---- 比赛传送门

昨晚成绩还好,AC A,B题,还能上分(到底有多菜)

补了C、D题,因为昨晚对C、D题已经有想法了,所以补起题来也快。(C题TLE了,D题想用并查集没好)

A

// http://codeforces.com/contest/1253/problem/A
/*
    如果YES,则b[i] - a[i] 在一个区间里的差肯定是相同的且不小于0
*/
#include<iostream>
#include<cstdio>
using namespace std;

int a[100005], b[100005];
int tar[100005];
int T, n, l, r, k;

int main()
{
    scanf("%d", &T);
    while(T--){
        bool flag = true;
        int pla = -1, num = 0, x = -1; // pla 来存储第一个差不为 0 的位置 x 存第一个不为 0 的差值
        scanf("%d", &n);
        for(int i = 0; i < n; i++) scanf("%d", &a[i]);
        for(int i = 0; i < n; i++){
            scanf("%d", &b[i]);
            tar[i] = b[i] - a[i];
            if(tar[i] != 0) {
                if(pla == -1) { pla = i; x = tar[i]; } // 找到第一个 不等的点
                num++; // num 来记录有多少个不同点
            }
        }

        if(pla == -1) printf("YES\n");
        else {
            for(int i = pla; i < n && num > 0; i++, num--){
                if(tar[i] != x){    // 一个个校对
                    flag = false;
                    break;
                }
            }
            if(x < 0) flag = false; // 特判第一个不等已经是 < 0 时
            if(flag) printf("YES\n");
            else printf("NO\n");
        }
    }
    return 0;
}

B

// http://codeforces.com/contest/1253/problem/B
/*
    因为分置的天数不需要最大或者最小,所以就直接处理最多天数的情况
*/
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;

int num[1000006], c;
int in[1000006]; // 记录员工是否已上班已下班,0表示没上班,1表示还没下班,2表示已经下班
int ans[1000006], ans_count;
int n, a, tot, num_c, ans_c;

int main()
{
    bool flag = true;
    scanf("%d", &n);
    for(int i = 1; i <= n; i++){
        scanf("%d", &a);
        if(a > 0){
            if(in[a] != 0) flag = false; // 如果已经上班了还上班,false
            else {  // 符合情况
                in[a]++;
                num[c++] = a;   // 记录已经上班的员工
                tot += a;
            }
        }
        else {
            if(in[-a] != 1) flag = false; // 已经下班了或者还没上班还下班,false
            else {          // 符合情况
                in[-a]++;
                tot += a;
            }
        }
        num_c++;
        if(tot == 0){   // tot == 0的时候既公司没人的时候
            ans[ans_c++] = num_c;
            num_c = 0;
            for(int j = 0; j < c; j++){ // 初始化 用 memset 会超时
                in[num[j]] = 0;
            }
            c = 0; // 初始化
        }
    }
    if(n & 1) flag = false;     // 特判 n 为奇数时
    if(tot != 0) flag = false;  // 特判最后一天 tot != 0 即公司的员工有人还没下班
    if(flag){                   // 符合情况 输出答案
        printf("%d\n", ans_c);
        for(int i = 0; i < ans_c; i++){
            printf("%d%c", ans[i], i == ans_c - 1 ? '\n' : ' ');
        }
    }
    else printf("-1\n");        // 不符合情况时输出 -1

    return 0;
}

C

参考题解(官方):

// http://codeforces.com/contest/1253/problem/C
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;

int n, m;
int sweet[200005];
long long ans[200005];

// 前缀和 O(nlogn) ---- 主要用在了排序
int main(){
    scanf("%d %d", &n, &m);

    for(int i = 1; i <= n; i++) scanf("%d", &sweet[i]);
    sort(sweet + 1, sweet + n + 1);

    long long tot = 0;
    for(int i = 1; i <= n; i++){
        tot += sweet[i];
        ans[i] = tot;
        if(i > m){      // 当吃的比m大的时候,只是比 i - m 一天多了个 ans[i - m](可以在纸上写写)
            ans[i] += ans[i - m];   // 前缀和
        }
        printf("%I64d%c", ans[i], i == n ? '\n' : ' ');
    }

    return 0;
}

/* O(n^2) TLE
int main()
{
    scanf("%d %d", &n, &m);
    for(int i = 0; i < n; i++){
        scanf("%d", &sweet[i]);
    }
    sort(sweet, sweet + n);

    double M = m;

    for(int i = 1; i <= n; i++){
        int day = ceil(i / M);
        int eat = i;
        int day_can = m;
        int day_s = 1;
        long long tot = 0;
        while(eat > 0){     // 模拟操作
            tot += sweet[eat - 1] * day_s;
//            printf("tot:%I64d sweet:%d day_s:%d can:%d\n", tot, sweet[eat - 1], day_s, day_can);
            day_can--;
            if(day_can == 0){
                day_s++;
                day_can = m;
            }
            eat--;
        }
//        printf("\n");
        ans[i] = tot;
//        printf("day:%d\n", day);
    }
    for(int i = 0; i < n; i++){
        printf("%d%c", sweet[i], i == n - 1 ? '\n' : ' ');
    }
    for(int i = 1; i <= n; i++){
        printf("%I64d%c", ans[i], i == n ? '\n' : ' ');
    }

    return 0;
}
*/

D

参考题解的出处在代码里

// http://codeforces.com/contest/1253/problem/D
// 参考:Marca 的 #65186644 的 AC 代码
#include<iostream>
#include<cstdio>
using namespace std;

int n, m, a, b, x, y, ans;
int par[200005];

void init(int n){
    for(int i = 1; i <= n; i++) par[i] = i;
}

int ff(int x){
    if(par[x] == x) return x;
    else return par[x] = ff(par[x]);
}

// 并查集解法
int main()
{
    scanf("%d %d", &n, &m);
    init(n);
    for(int i = 0; i < m; i++){
        scanf("%d %d", &a, &b);
        x = ff(a);
        y = ff(b);
        // 把点大的都做树的根节点
        if(x > y) swap(x, y);
        par[x] = y;
    }

    for(int i = 1; i <= n; i++){
        x = ff(i);      // ff函数已包含路径压缩
        while(i < x){
            y = ff(i);
            if(x != y){ // 不在一个区间里 合并
                ans++;  // 路径 ++
                // 把点大的做树的根节点
                if(y > x) swap(x, y);
                par[y] = x;
            }
            i++;
        }
    }

    printf("%d\n", ans);

    return 0;
}

记录我这菜鸟的成长经历

原文地址:https://www.cnblogs.com/Ayanowww/p/11875815.html

时间: 2024-10-08 05:49:27

【cf比赛记录】Codeforces Round #600 (Div. 2)的相关文章

【题解】Codeforces Round #600(Div.2)

Codeforces Round #600(Div.2) https://codeforces.com/contest/1253/problem A.Single Push 思路:数组各位相减,得到b-a之后的.如果全为0,或者只有一段非0且数字相同则可行,否则不可行.具体实现的话,可以左右两边指针向中间搜到第一个不为0的数,再判断中间是否均为同一个数.复杂度\(O(n)\). 注意:多组数据一定要判断是否需要清空.这里我a[n+1]没有清0,结果WA on test55-- AC代码: #in

Codeforces Round #600 (Div. 2) E. Antenna Coverage

Codeforces Round #600 (Div. 2) E. Antenna Coverage(dp) 题目链接 题意: m只蚂蚁,每只蚂蚁的位置是\(x_i\),分数是\(s_i\),覆盖范围是\([x_i - s_i; x_i + s_i]\),每个硬币可以使一直蚂蚁的\(s_i\)+1,求覆盖整个\([1;m]\)的最少硬币 思路: \(f[pos][0]\)表示\([1,pos]\)没有被覆盖还要花费的最少硬币,\(f[pos][1]\)表示\([1,pos]\)被覆盖的最小花费硬

Codeforces Round #600 (Div. 2)

A - Single Push 题意:给数组a和数组b,可以选择一段连续的区间[l,r]使得ai全部加k(k>0)至多一次.求能不能从a变成b. 题解:一开始作差排序去重,然后判断差是不是只有1个(且>=0)或只有两个(且c1=0,c2>0),但这样是错的,比如下面的样例. 1 5 1 1 1 1 1 2 1 2 2 2 因为虽然差都是1但不是连续的区间. 做法是作差,然后判断是否有至多一个正的方波.可以用两个变量,一个记录是否进入了方波,且方波的高是多少.另一个记录是否离开了方波. #

第五天打卡 Codeforces Round #600 (Div. 2)

A题: #include<bits/stdc++.h> using namespace std; #define ll long long const int N = 1e5+10; int a[N],b[N]; int main(){ int t; scanf("%d",&t); while(t--) { int n; scanf("%d",&n); int need = -9999999; bool ok = true; for(in

cf之路,1,Codeforces Round #345 (Div. 2)

 cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅.....       其实这个应该是昨天就写完的,不过没时间了,就留到了今天.. 地址:http://codeforces.com/contest/651/problem/A A. Joysticks time limit per test 1 second memory limit per test 256

Codeforces Round #575 (Div. 3)记录

Codeforces Round #575 (Div. 3)记录 错过了上分的机会,上次不小心打了个div. 2结果直接掉了100多分. 我绿了,也变弱了.找下场Div. 3上上分吧. A 随便写了. 我的思路是三个东西先排序,一个人先拿最少的,另一个人拿次少的. 然后看剩下的能不能填补相差,如果能的话继续左右两边各补,补到剩1或0为止. 其实上面说这么多,答案就等于\(\lfloor \frac{a+b+c}{2} \rfloor\). 我是sb B 这些数与大小无关,我们直接统计有多少个奇数

Codeforces Round #617 (Div. 3) 题解

目录 Codeforces Round #617 (Div. 3) 题解 前言 A. Array with Odd Sum 题意 做法 程序 B. Food Buying 题意 做法 程序 C. Yet Another Walking Robot 题意 做法 程序 D. Fight with Monsters 题意 做法 程序 E1. String Coloring (easy version) 题意 做法 程序 E2. String Coloring (hard version) 题意 做法

Codeforces Round #354 (Div. 2) ABCD

Codeforces Round #354 (Div. 2) Problems # Name     A Nicholas and Permutation standard input/output 1 s, 256 MB    x3384 B Pyramid of Glasses standard input/output 1 s, 256 MB    x1462 C Vasya and String standard input/output 1 s, 256 MB    x1393 D T

Codeforces Round #257 div.2 D or 450D Jzzhu and Cities【最短路】

Codeforces Round #257 div.2 D or 450D Jzzhu and Cities[最短路] 题目链接:点击打开 题目大意: 在一个国家中有n个城市(城市编号1~n),m条公路和k条铁路,编号为1的城市为首都,为了节约,不需要的铁路需要关闭,问在保证首都到其余所有城市的最短路不变的条件下,最多有多少条铁路是不需要的. 解法: 这个题比较麻烦,保证首都到其余城市的最短路不变,要求出最多有多少条铁路是不需要的,那肯定是从最短路的代码上下手了,我们首先考虑dijkstra算法