CF Round #600 (Div 2) 解题报告(A~E)

A:Single Push

  • 采用差分的思想,让\(b-a=c\),然后观察\(c\)序列是不是一个满足要求的序列

  • #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5 + 10;
    int T, n;
    int a[maxn], b[maxn];
    int c[maxn];
    int main()
    {
    cin >> T;
    while(T--)
    {
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) c[i] = 0;
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
    for(int i = 1; i <= n; i++) scanf("%d", &b[i]);
    int flag = 1;
    for(int i = 1; i <= n; i++)
    {
    c[i] = b[i] - a[i];
    if(c[i] < 0)
    {
    puts("NO"); flag = 0;
    break;
    }
    }
    if(!flag) continue; for(int i = 1; i <= n; i++)
    {
    if(c[i] == 0) continue;
    for(int j = i; j <= n; j++)
    {
    if(c[i] == c[j])
    {
    i = j;
    continue;
    }
    else
    {
    if(c[j] != 0)
    {
    flag = 0;
    break;
    }
    if(c[j] == 0)
    {
    for(int k = j; k <= n; k++)
    {
    if(c[k] != 0)
    {
    flag = 0;
    i = k;
    j = k;
    break;
    }
    }
    }
    }
    if(!flag) break;
    }
    if(!flag) break;
    }
    if(flag) puts("YES");
    else puts("NO");
    }
    return 0;
    }
  • 这份代码真是又丑又长...

  • 看了一下CF上学了一下这个写法。

  • #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5 + 10;
    int a[maxn], n, T, cnt;
    bool flag;
    int main()
    {
    scanf("%d", &T);
    while(T--)
    {
    scanf("%d", &n); cnt = 0; flag = 1;
    for(int i = 1; i <= n; i++)
    scanf("%d", &a[i]);
    for(int i = 1, x; i <= n; i++)
    {
    scanf("%d", &x); a[i] = x - a[i];
    if(a[i] < 0) flag = 0;
    if(a[i] != a[i-1]) cnt++;
    }
    if(cnt > 2 || (cnt == 2 && a[n] != 0)) flag = 0;
    if(flag) puts("YES");
    else puts("NO");
    }
    return 0;
    }
  • 相比我写的简洁明了了很多。

B:Silly Mistake

  • 暴力模拟就行

  • #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5 + 10;
    int a[maxn], n;
    int vis[1000000+10];
    int cnt, c[maxn];
    int isv[1000000+10];
    int main()
    {
    cin >> n;
    for(int i = 1; i <= n; i++)
    scanf("%d", &a[i]);
    if(n % 2 == 1)
    {
    puts("-1");
    return 0;
    } int tot = 0, num = 0;
    vector<int> d;
    for(int i = 1, x; i <= n; i++)
    {
    x = a[i];
    if(x > 0)
    {
    if(vis[x] == 0 && isv[x] == 0)
    {
    vis[x] = 1; isv[x] = 1;
    d.push_back(x); num++;
    } else {
    puts("-1");
    return 0;
    }
    } else if(x < 0)
    {
    if(vis[abs(x)] == 1)
    {
    vis[abs(x)] = 0;
    tot += 2;
    num -= 1;
    }
    else if(vis[abs(x)] == 0)
    {
    puts("-1");
    return 0;
    }
    } if(num == 0)
    {
    c[++cnt] = tot;
    tot = 0;
    while(d.size())
    {
    int xx = d.back();
    isv[xx] = 0;
    d.pop_back();
    }
    }
    }
    if(num != 0)
    {
    puts("-1");
    return 0;
    } cout << cnt << endl;
    for(int i = 1; i <= cnt; i++)
    printf("%d ", c[i]);
    puts(""); return 0;
    }

C:Sweet Eating

  • 排序+贪心+前缀和

  • 假如说现在考虑一共吃\(i\)颗糖,那么首先肯定的一点是,每天吃\(m\)颗糖,我要尽可能的打满这\(m\),很显然的贪心。

  • 对于吃\(k\)颗糖,如果不考虑天数要乘上一个数,那么其实就是前缀和。

  • 对于开启了新的一天,实际上是要把糖度高的放到第一天,然后把前面吃\(i-m\)颗糖的糖度加上。

  • 这么说可能不太好理解,结合样例来看。

    • 目前糖度是\(2,3,4,4\),\(m=2\)。
    • 吃\(1/2\)颗糖结果显然是在第一天都吃完,答案为\(2,5\)。
    • 吃\(3\)颗糖的情况就需要我们开启新的一天,那么就是将\(3,4\)放到第一天,\(2\)放到第二天。
    • 也就是说\(2\)被翻倍了。\(ans(3)=sum(3)+ans(1)\)
    • 吃\(4\)颗糖的情况,那其实就是要把\(2,3\)放到第二天,\(4,4\)放到第一天。\(ans(4)=sum(4)+ans(2)\)。
  • #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn = 2e5 + 10;
    int a[maxn], n, m;
    ll c[maxn];
    int main()
    {
    cin >> n >> m;
    for(int i = 1; i <= n; i++)
    scanf("%d", &a[i]);
    sort(a+1, a+1+n);
    ll sum = 0;
    for(int i = 1; i <= n; i++)
    {
    sum += a[i]; c[i] = sum;
    if(i >= m) c[i] += c[i-m];
    }
    for(int i = 1; i <= n; i++)
    printf("%lld ", c[i]); puts("");
    return 0;
    }

D: Harmonious Graph

  • 并查集

  • 考虑所有连通块,记录每个连通块中最大的数字。

  • 然后枚举\(i\),当\(i\)所在的连通块内最大的数字大于\(i\)时,判断\(i\)和\(i+1\)是否在一个连通块中,如果是,则跳过,否则连接\(i\)和\(i+1\)并让\(ans++\)。

  • #include<bits/stdc++.h>
    using namespace std; const int maxn = 2e5 + 10;
    int n, m; int fa[maxn], mx[maxn];
    int get_fa(int x)
    {
    if(x == fa[x]) return x;
    return fa[x] = get_fa(fa[x]);
    } bool merge_dis(int x, int y)
    {
    x = get_fa(x), y = get_fa(y);
    if(x == y) return false;
    fa[y] = x;
    mx[x] = max(mx[x], mx[y]);
    return true;
    } int main()
    {
    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m;
    for(int i = 1; i <= n; i++) fa[i] = mx[i] = i;
    for(int i = 1, x, y; i <= m; i++)
    {
    cin >> x >> y;
    merge_dis(x, y);
    }
    int ans = 0;
    for(int i = 1; i <= n; i++)
    {
    if(mx[get_fa(i)] > i)
    {
    if(merge_dis(i, i + 1)) ans++;
    }
    }
    cout << ans << endl;
    return 0;
    }

E:Antenna Coverage

  • \(dp\),参考: https://www.cnblogs.com/Willems/p/11876315.html

  • 考虑\(f(i)\)表示覆盖\(i\)~\(m\)的最小花费。初态\(f(m+1)=0\),最后答案为\(f(1)\)。

  • 倒序枚举。

  • 当前枚举到点\(i\),如果\(i\)已经被覆盖了,那么有\(f(i)=f(i+1)\)。

  • 如果\(i\)没有被覆盖,枚举\(n\)个天线,考虑左端点大于\(i\)的那个天线。

  • 设\(dis=x-s-i\),即覆盖到区间左端点到\(i\)的距离。

  • 因为同时左右扩展,所以也向右边延伸到了\(dis\)。

  • 那么有\(f(i)=min\{dis+f(x+s+dis)\}\)。

  • #include<bits/stdc++.h>
    using namespace std; const int maxn = 80 + 10;
    const int maxm = 1e5 + 10;
    int n, m, f[maxm]; struct Node{
    int l, r;
    bool operator < (Node a){
    if(a.l == l) return r < a.r;
    return l < a.l;
    }
    }h[maxn]; int main()
    {
    scanf("%d%d", &n, &m);
    memset(f, 0x3f, sizeof f);
    for(int i = 1, p, s; i <= n; i++)
    {
    scanf("%d%d", &p, &s);
    h[i] = {max(p-s, 1), min(p+s, m)};
    } sort(h+1, h+1+n); //for(int i=1; i<=n;i++) cout << h[i].l << " " << h[i].r << endl; f[m+1] = 0;
    for(int i = m; i > h[n].r; i--)
    f[i] = m - i + 1;
    for(int i = 1; i <= n; i++)
    for(int j = h[i].l; j <= h[i].r; j++)
    f[j] = 0; for(int i = m; i >= 1; i--)
    {
    if(!f[i]) f[i] = f[i+1];
    else
    {
    for(int j = 1; j <= n; j++)
    {
    if(h[j].l > i)
    {
    int d = h[j].l - i;
    int num = min(h[j].r+d, m);
    f[i] = min(f[i], d + f[num+1]);
    }
    }
    }
    } cout << f[1] << endl;
    return 0;
    }

CF Round #600 (Div 2) 解题报告(A~E)的更多相关文章

  1. Codeforces Round #382 (Div. 2) 解题报告

    CF一如既往在深夜举行,我也一如既往在周三上午的C++课上进行了virtual participation.这次div2的题目除了E题都水的一塌糊涂,参赛时的E题最后也没有几个参赛者AC,排名又成为了 ...

  2. Codeforces Round #324 (Div. 2)解题报告

    ---恢复内容开始--- Codeforces Round #324 (Div. 2) Problem A 题目大意:给二个数n.t,求一个n位数能够被t整除,存在多组解时输出任意一组,不存在时输出“ ...

  3. Codeforces Round #216 (Div. 2)解题报告

    又范低级错误! 只做了两题!一道还被HACK了,囧! A:看了很久!应该是到语文题: 代码:#include<iostream> #include<];    ,m2=;    ;i ...

  4. Codeforces Round #384 (Div. 2) 解题报告

    这场CF水题都非常的水,D题如果对树.DFS相关比较熟练的话也不难.比赛时前三题很快就过了,可是因为毕竟经验还是太少,D题就卡住了.比赛之后A题还因为没理解对题意fst了--(为什么这次就没人来hac ...

  5. Codeforces Round #383 (Div. 2) 解题报告

    本来是打算所有半夜进行的CF都不参加的,但看到这次比赛22:35就开始,还是没有忍住orz--晚上总是不够清醒,做题思维不如白天活跃,低级错误常常出现.出的比较早的C因为一个书写错误有点小bug,在比 ...

  6. Codeforces Round #380 (Div. 2) 解题报告

    第一次全程参加的CF比赛(虽然过了D题之后就开始干别的去了),人生第一次codeforces上分--(或许之前的比赛如果都参加全程也不会那么惨吧),终于回到了specialist的行列,感动~.虽然最 ...

  7. Codeforces Round #379 (Div. 2) 解题报告

    题目地址 本次CF是在今天早上深夜进行,上午有课就没有直接参加.今天早上上课坐到后排参加了virtual participation.这次CF前面的题目都非常的水,不到10分钟就轻松过了前两题,比较郁 ...

  8. Codeforces Round #544 (Div. 3)解题报告

    A.Middle of the Contest 考虑把输入的时间单位化成分钟,相加除以2就好了 #include<bits/stdc++.h> using namespace std; # ...

  9. Codeforces Round #230 (Div. 2) 解题报告

    Problem A. Nineteen 思路: 除了首位像连的n,其他的字母不能共用nineteenineteen.所以可以扫描一遍所有的字符串将出现次数保存到hash数组,n的次数(n - 1) / ...

随机推荐

  1. 应用Redis分布式锁解决重复通知的问题

    研究背景: 这几天被支付宝充值后通知所产生的重复处理问题搞得焦头烂额, 一周连续发生两次重复充钱的杯具, 发事故邮件发到想吐..为了挽回程序员的尊严, 我用了Redis的锁机制. 事故场景: 支付宝下 ...

  2. springboot 解决Jackson导致Long型数据精度丢失问题

    代码中注入一个bean即可: /** * 解决Jackson导致Long型数据精度丢失问题 * * @return */ @Bean("jackson2ObjectMapperBuilder ...

  3. 2019-11-29-WPF-非客户区的触摸和鼠标点击响应

    原文:2019-11-29-WPF-非客户区的触摸和鼠标点击响应 title author date CreateTime categories WPF 非客户区的触摸和鼠标点击响应 lindexi ...

  4. System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false

    多线程程序中,新创建的线程不能访问UI线程创建的窗口控件,这时如果想要访问窗口的控件,发现无法对其控制. 这时可将窗口构造函数中的CheckForIllegalCrossThreadCalls设置为f ...

  5. C#利用newtonsoft.json读取.so配置文件内容

    今天花 了点时间来使用 C#读取json文件 ,文件后缀为 .so文件 ,也是基于文件流的形式 获取 对象 ,然后解析; 之所以尝试 使用 json读取 ,是因为其配置文件的格式 更为友好 和方便,直 ...

  6. NetCoreApi框架搭建(二、Nlog使用配置)

    本文只配置了简单文件存储 1.添加nuget包 2.添加日志配置文件nlog.config 这里配置了三个target区分不同的日志,具体配置需要自己研究,推荐链接https://www.cnblog ...

  7. python 变量作用域、闭包

    先看一个问题: 下面代码输出的结果是0,换句话说,这个fucn2虽然已经用global声明了variable1,但还是没有改变变量的值 def func1(): variable1=0 def fun ...

  8. Vue.js项目实战-打造线上商城

    首先上一下完成后的效果: 首页: 商品详情页: 购物车页(其实还有个订单页,只是和购物车页基本类似,所以就不截图啦): 开始项目: 由于涉及的是前后端分离,所以我们的后台数据就模拟存储于浏览器端(co ...

  9. 设计模式之(九)桥接模式(Bridge)

    桥接模式是怎么诞生的呢?来看一个场景. 一个软件企业开发一套系统,要兼容所有的不同类型硬件和和各种操作系统.不同种类硬件主要是 电脑.平板电脑.手机.各种操作系统是苹果系统.windows 系统.Li ...

  10. Centos 7 JDK 安装(默认之前没有安装过)

    第一步: 安装JDK,先检查JDK是否存在,输入以下命令回车: java -version 没有安装过会显示: [root@heyouhao /]# java -version [root@heyou ...