Codeforces Round #850 (Div. 2, based on VK Cup 2022 - Final Round)(A~E)

news2024/10/2 6:29:21

t宝酱紫喜欢出这种分类讨论的题?!

A1. Non-alternating Deck (easy version)

给出n张牌,按照题目给的顺序分给两人,问最后两人手中各有几张牌。

思路:模拟。

AC Code:

#include <bits/stdc++.h>

typedef long long ll;
const int N = 1e5 + 5;
int t, n;

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    std::cin >> t;
    while(t --) {
        std::cin >> n;
        n --;
        ll cnta = 1, cntb = 0;
        int cnt = 0, res = 0;
        for(int i = 2; n > 0; i ++) {
            if(cnt == 2) res ^= 1, cnt = 0;
            if(res == 0)
                cntb += std::min(n, i), n -= std::min(n, i);
            else
                cnta += std::min(n, i), n -= std::min(n, i);
            cnt ++;
        }
        std::cout << cnta << ' ' << cntb << '\n';
    }
    return 0;
}

A2. Alternating Deck (hard version)

在A1的基础上分了两种颜色,问最后每人手中每种颜色有几张。

思路:还是模拟。

AC Code:

#include <bits/stdc++.h>

typedef long long ll;
const int N = 1e5 + 5;
int t, n;

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    std::cin >> t;
    while(t --) {
        std::cin >> n;
        int pos = 1, cntp = 0, cnt = 0, res = 0;
        int cntaw = 0, cntab = 0, cntbw = 0, cntbb = 0;
        for(int i = 1; i <= n; i ++) {
            if(cntp == pos) {
                res ++;
                pos ++;
                cntp = 0;
                if(res & 1)
                    cnt ^= 1;
            }
            if(!cnt) {
                if(i & 1)
                    cntaw ++;
                else
                    cntab ++;
            }
            else {
                if(i & 1)
                    cntbw ++;
                else
                    cntbb ++;
            }
            cntp ++;
        }
        std::cout << cntaw << ' ' << cntab << ' ' << cntbw << ' ' << cntbb << '\n'; 
    }
    return 0;
}

B. Cake Assembly Line

给出一个蛋糕的位置序列和加巧克力的机器头的位置序列,调整两条线的相对顺序,是否可以满足机器头加入巧克力全部位于蛋糕上的要求。

思路:从头开始找范围的交集,如果交集不为空集就可以满足。当然,机器头的半径如果大于蛋糕的半径,那一定是不可以的。

AC Code:

#include <bits/stdc++.h>

typedef long long ll;
const int N = 2e5 + 5;
int t, n, w, h;
ll a[N], b[N];

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    std::cin >> t;
    while(t --) {
        std::cin >> n >> w >> h;
        for(int i = 1; i <= n; i ++) {
            std::cin >> a[i];
        }
        for(int i = 1; i <= n; i ++) {
            std::cin >> b[i];
        }
        if(w < h) {
            std::cout << "NO" << '\n';
            continue;
        }
        ll L = a[1] - w + h, R = a[1] + w - h;
        for(int i = 2; i <= n; i ++) {
            ll lb = L + b[i] - b[i - 1], rb = R + b[i] - b[i - 1];
            // std::cout << lb << ' ' << rb << '\n';
            ll l = a[i] - w + h, r = a[i] + w - h;
            // std::cout << l << ' ' << r <<'\n';
            L = std::max(l, lb), R = std::min(r, rb);
            // L = std::max(l, L);
            // R = std::min(R, r);
            // std::cout << l << ' ' << r << ' ' << L << ' ' << R << '\n';
        }
        std::cout << (L <= R ? "YES" : "NO") << '\n';
    }
    return 0;
}

C. Monsters (easy version)

给出一个序列的怪物的生命值,有两种操作,一是对其中一个怪物打击,使得它的生命值-1;二是对于所有的怪物进行打击,每一个都-1,如果在一次打击中有怪物生命值降为0,则可以重复该操作。求操作一使用次数最少是多少。

思路:最优的操作是使得操作数组存在1~x连续序列,数字必须从1开始,尽可能使得数字变大,不能通过一次操作二减去的那只能操作一减去了。

AC Code:

#include <bits/stdc++.h>

typedef long long ll;
const int N = 2e5 + 5;
int t, n;
ll a[N];

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    std::cin >> t;
    while(t --) {
        std::cin >> n;
        for(int i = 1; i <= n; i ++) {
            std::cin >> a[i];
        }
        std::sort(a + 1, a + 1 + n);
        ll pos = 1, ans = a[1] - pos;
        for(int i = 2; i <= n; i ++) {
            if(a[i] == pos)
                continue;
            pos ++;
            ans += (a[i] - pos);
        }
        std::cout << ans << '\n';
    }
    return 0;
}

D. Letter Exchange

给出m个有三个字符的字符串,每次可以用两个字符串交换字符,问最少交换几次,可以的使得每个字符串的三个字符都不一样。

思路:大佬的思路

AC Code:

#include <bits/stdc++.h>

typedef long long ll;
const int N = 1e5 + 5;
int t, n;
std::string s;

struct node {
    int a, b;
    char c, d;
};

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    std::cin >> t;
    char ch[4] = "win";
    const std::array<int, 3> all1 = {1, 1, 1};
    while(t --) {
        std::cin >> n;
        std::map<std::array<int, 3>, std::vector<int>> mp;
        int sum = 0;
        for(int i = 1; i <= n; i ++) {
            std::cin >> s;
            std::array<int, 3> cnt = {};
            for(auto c : s) {
                if(c == 'w') cnt[0] ++;
                else if(c == 'i') cnt[1] ++;
                else cnt[2] ++;
            }
            if(cnt == all1) continue;
            mp[cnt].push_back(i);
            sum ++;
        }
        std::vector<node> op;
        while(sum) {
            int max = 0;
            std::array<int, 3> p1, p2;
            for(auto &[x1, v1] : mp) {
                if(v1.empty()) continue;
                for(auto &[x2, v2] : mp) {
                    if(x1 == x2) continue;
                    if(v2.empty()) continue;
                    int c = 0;
                    for(int i = 0; i < 3; i ++) {
                        if(x1[i] < 1 && x2[i] > 1) c ++;
                        else if(x2[i] < 1 && x1[i] > 1) c ++;
                    }
                    if(c > max) {
                        max = c;
                        p1 = x1, p2 = x2;
                    }
                }
            }
            int t1 = mp[p1].back();
            int t2 = mp[p2].back();
            mp[p1].pop_back();
            mp[p2].pop_back();
            char c1, c2;
            for(int i = 0; i < 3; i ++) {
                if(p2[i] >= 2) c2 = ch[i], p2[i] --, p1[i] ++;
                else if(p1[i] >= 2) c1 = ch[i], p1[i] --, p2[i] ++;
            }
            if(p1 != all1) mp[p1].push_back(t1);
            else sum --;
            if(p2!= all1) mp[p2].push_back(t2);
            else sum --;
            op.push_back({t1, t2, c1, c2});
        }
        std::cout << op.size() << '\n';
        for(auto [a, b, c, d] : op) {
            std::cout << a << ' ' << c << ' ' << b << ' ' << d << '\n';
        }

    }
    return 0;
}

E. Monsters (hard version)

与C相同,不过区别是要对于每个i输出所需的最少操作一数量。

思路:我们的操作是将原数组组成一个+1递增的数列,对于每次向后加入的数,如果它比较小,那对于现有的数组来说没什么影响;但是若是加入的数比较大,那就需要考虑它的影响了。但是例如1,1,3,3,3,5来说,最后变成的数组为1,1,2,3,3,4,而其中第二个数和第四个数对于答案是没有贡献的,而去掉重复的元素后,前i个数的结果为:其中n是数组所能达到的最大的数。

引用大佬的结论和证明:

AC Code:

#include <bits/stdc++.h>

typedef long long ll;
#define INF 0x3f3f3f3f3f3f3f3f
#define int long long
const int N = 2e5 + 5;
int t, n;
int a[N];

struct SegmentTree {

    struct node {
        int l, r, max, add;
    } tr[N << 2];

    void pushup(int u) {
        tr[u].max = std::max(tr[u << 1].max, tr[u << 1 | 1].max);
    }

    void build(int u, int l, int r) {
        tr[u] = {l, r, -INF, 0};
        if(l == r) {
            tr[u].max = -l;
            return;
        }
        int mid = l + r >> 1;
        build(u << 1, l, mid);
        build(u << 1 | 1, mid + 1, r);
        pushup(u);
    }

    void pushdown(int u) {
        if(tr[u].add) {
            tr[u << 1].add += tr[u].add;
            tr[u << 1 | 1].add += tr[u].add;
            tr[u << 1].max += tr[u].add;
            tr[u << 1 | 1].max += tr[u].add;
            tr[u].add = 0;
        }
    }

    void modify(int u, int l, int r, int c) {
        if(tr[u].l >= l && tr[u].r <= r) {
            tr[u].max += c;
            tr[u].add += c;
        }
        else {
            pushdown(u);
            int mid = tr[u].l + tr[u].r >> 1;
            if(l <= mid) modify(u << 1, l, r, c);
            if(r > mid) modify(u << 1 | 1, l, r, c);
            pushup(u);
        }
    }

    int query(int u) {
        if(tr[u].l == tr[u].r) return tr[u].l;
        pushdown(u);
        if(tr[u << 1].max > 0) return query(u << 1);
        return query(u << 1 | 1);
    }

} ST;

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    std::cin >> t;
    while(t --) {
        std::cin >> n;
        for(int i = 1; i <= n; i ++) {
            std::cin >> a[i];
        }
        ST.build(1, 1, n);
        int cnt = 0, s = 0;
        for(int i = 1; i <= n; i ++) {
            cnt ++, s += a[i];
            ST.modify(1, a[i], n, 1);
            if(ST.tr[1].max > 0) {
                int x = ST.query(1);
                ST.modify(1, x, n, -1);
                cnt --, s -= x;
            }
            std::cout << s - cnt * (cnt + 1) / 2 << " \n"[i == n];
        }
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/369950.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot+Vue前后端分离管理系统03:后端

后端项目初始化 1、创建一个springboot 2.7.8项目 2、导入依赖 <!-- web --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- mysql -->…

MIND——Modality independent neighbourhood descriptor 模态无关邻域描述符

参考&#xff1a;https://blog.mbedded.ninja/programming/signal-processing/image-processing/image-registration/modality-independent-neighbourhood-descriptor-mind/《MIND: Modality independent neighbourhood descriptor for multi-modal deformable registration》论…

【离线数仓-6-数据仓库开发ODS层设计要点】

离线数仓-6-数据仓库开发ODS层设计要点离线数仓-6-数据仓库开发ODS层1.数据仓库开发ODS层设计要点2.ODS层用户行为日志表1.hive中复杂结构体复习1.array2.map3.struct 复杂结构4.嵌套格式2.hive中针对复杂结构字符串的练习1.针对ods层为json格式数据的练习2.用户行为日志表的设…

Linux学习(5)nano与正确关机方法sync shutdown

目录 文书编辑器 nano 正确的关机方法: sync, shutdown, reboot, halt, poweroff, init 数据同步写入磁盘&#xff1a;sync 惯用的关机命令&#xff1a; shutdown 重新启动&#xff0c;关机&#xff1a; reboot, halt, poweroff 切换运行等级&#xff1a; init 以下内容转载…

linux编程之经典多级时间轮定时器(C语言版)

一. 多级时间轮实现框架 上图是5个时间轮级联的效果图。中间的大轮是工作轮&#xff0c;只有在它上的任务才会被执行&#xff1b;其他轮上的任务时间到后迁移到下一级轮上&#xff0c;他们最终都会迁移到工作轮上而被调度执行。 多级时间轮的原理也容易理解&#xff1a;就拿时…

技术分享| anyRTC回声消除算法进化

本文将从基础概念、经典算法、主要挑战&#xff0c;以及人工智能回声消除技术探索等方面&#xff0c;分享anyRTC在 AEC 技术方面的实践及效果。 一.什么是回声消除 回音消除一直是语音通信的难点&#xff0c;最早的回声消除是从电话兴起的时候就有了&#xff0c;电话机的硬件…

postgres 源码解析51 LWLock轻量锁--2

本篇将着重讲解LWLock涉及的主要API工作流程与实现原理&#xff0c;相关基础知识见回顾&#xff1a;postgres 源码解析50 LWLock轻量锁–1 API介绍 函数API功能CreateLWLocks分配LWLocks所需的内存并进行初始化LWLockNewTrancheId分配新的Tranche ID,供用户使用Extension模块…

Helm安装Harbor

一、介绍 1.1 Harbor Harbor 是由 VMware 公司为企业用户设计的 Registry Server 开源项目&#xff0c;包括了权限管理 (RBAC)、LDAP、审计、管理界面、自我注册、HA 等企业必需的功能&#xff0c;同时针对中国用户的特点&#xff0c;设计镜像复制和中文支持等功能。目前该项…

说说Java“锁“ 事

文章目录前言大厂面试题复盘 —— 并发编程高级面试解析从轻松的乐观锁和悲观锁开讲通过8种情况演示锁运行案例&#xff0c;看看我们到底锁的是什么公平锁和非公平锁可重入锁(又名递归锁)死锁及排查写锁(独占锁)/读锁(共享锁)自旋锁SpinLock无锁 -> 独占锁 -> 读写锁 -&g…

五种IO模型以及select多路转接IO模型

目录 一、典型IO模型 1.1 阻塞IO 1.2 非阻塞IO 1.3 信号驱动I0 1.4 IO多路转接 1.5 异步IO 多路转接的作用和意义 二、多路转接IO模型&#xff08;select&#xff09; 2.1 接口 2.2 接口当中的事件集合&#xff1a; fd_set 2.2 select使用事件集合&#xff08;位图&am…

ip公司和soc公司是什么?

IP 公司和 SoC 公司都是半导体行业的重要组成部分&#xff0c;但它们的角色和职责略有不同。IP&#xff08;Intellectual Property&#xff09;公司主要提供可重用的知识产权组件&#xff0c;也称为 IP 核或 IP 模块&#xff0c;这些组件可以在设计芯片的过程中被集成到芯片中。…

Git代码冲突-不同分支之间的代码冲突

1、解决思路在团队开发中&#xff0c;提交代码到Git仓库时经常会遇到代码冲突的问题。- 原因&#xff1a;多人对相同的文件进行了编辑&#xff0c;造成代码存在差异化- 解决方案&#xff1a;1. 使用工具或git命令对比不同分支代码的差异化2. 把不同分支中有效代码进行保留&…

[译文] 基于PostGIS3.1 生成格网数据

根据格网进行数据统计与分析是一种常用的方法&#xff0c;相比自然地理边界与行政管理边界而言&#xff0c;使用格网有如下特点&#xff1a;每个格网之间地位相等&#xff0c;没有上下级之分。每个格网的面积都相等。相邻两个格网单元中心点之间距离相等。适用于将数据从“空间…

ThreeJS加载公路GeoJson数据实现流光效果

threejs加载公路geojson数据,跟加载行政区域的原理一样,唯一不同的是geojson格式不一样,路线并不是连贯起来的,按照路段进行的拆分,在加载的时候问题不大,正常解析然后转墨卡托投影,但是在做流光效果时,需要对geojson进行重新组合. 实现效果:

Android:反编译apk踩坑/apktool/dex2jar/JDGUI

需求描述 想要反编译apk文件&#xff0c;搜到了这篇博客&#xff1a;Android APK反编译就这么简单 详解&#xff08;附图&#xff09;&#xff0c;非常有参考价值~但其中的工具下载链接都已404&#xff0c;而本杂鱼实际操作的过程中也出现了亿点点点点点点的问题&#xff0c;于…

电子技术——反馈对放大器极点的影响

电子技术——反馈对放大器极点的影响 放大器的频率响应和稳定性可以直接由其极点决定。因此我们将深入反馈对放大器极点的影响。 稳定性和极点位置 我们首先讨论稳定性和极点位置的关系。首先我们给出结论&#xff0c;对于任何一个稳定的放大器&#xff0c;其极点都处在 sss …

prometheus + alterManager + 飞书通知,实现服务宕机监控告警;实测可用

架构设计图 最终效果图 项目准备 xml依赖 <!-- 监控相关 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>io.…

Elasticsearch7.8.0版本进阶——段合并

目录一、段的概述1.1、段的概念1.2、段的缺点1.3、如何解决段数量暴增问题二、段合并的流程三、段合并的注意事项一、段的概述 1.1、段的概念 每一 段 本身都是一个倒排索引。 1.2、段的缺点 由于自动刷新流程每秒会创建一个新的段 &#xff0c;这样会导致短时间内的段数量…

interrupt多线程设计模式

1. 两阶段终止-interrupt Two Phase Termination 在一个线程T1中如何“优雅”终止线程T2&#xff1f;这里的【优雅】指的是给T2一个料理后事的机会。 错误思路 ● 使用线程对象的stop()方法停止线程&#xff08;强制杀死&#xff09; —— stop&#xff08;&#xff09;方法…

Linux内核的虚拟内存(MMU、页表结构)

前言&#xff1a;内存是程序得以运行的重要物质基础。如何在有限的内存空间运行较大的应用程序&#xff0c;曾是困扰人们的一个难题。为解决这个问题&#xff0c;人们设计了许多的方案&#xff0c;其中最成功的当属虚拟内存技术。Linux作为一个以通用为目的的现代大型操作系统&…