Educational Codeforces Round 95 (Rated for Div. 2)A-D题解

基于Gardner环的QPSK定时同步MATLAB仿真:四倍采样与多场景性能分析 本文详细介绍了基于Gardner环的QPSK定时同步MATLAB仿真方法,重点分析了四倍采样技术在定时同步中的应用与性能优化。通过MATLAB代码实例展示了Gardner环的实现原理、多场景性能分析及常见问题解决方案,为数字通信系统的定时同步设计提供实用参考。 阅读详情

Educational Codeforces Round 95 (Rated for Div. 2)A-D题解
//写于rating值1987/2184
//这场unrated…很迷的一场。
//看完A的题面,内心:“这不傻逼题么”,一看样例:“???????”。“难道是我读错题意了???”,回去又看了两遍题意,然后官方开始发公告。大概在11min的时候修改了A的样例和评测数据。
//13分钟时过掉了A,再13分钟过掉了B和C,看了D一半的题面后官方发了公告说unrated,光速赶在门禁前飞回寝室…
//D的结论以及用set和优先队列实现的思路都已经推导出来,但是set的一些函数操作并不熟悉,趁此机会学习了一波

A题
水题

题意为一开始你有1根木棒,使用1根木棒和1份燃油可以做1个火把,现在你希望做k个火把。你可以进行任意次交易,每次交易你可以选择以下两种交易方式:
1.用1根木棒交换x根木棒
2.用y根木棒交换1份燃油
现在问你最少需要几次交易可以制作出k个火把。

制作k个火把需要至少k根木棒和k份燃油。
首先我们手上是没有燃油的,且燃油只能用木棒交换获得,那么k份燃油就需要至少进行k次第二种交易用k×\times×y根木棒交换获得,总共就至少需要k×\times×y+k根木棒。而第一种交易方式可以看作每次交易增加x-1根木棒。因此所需第一种交易的最少次数就是(k×\times×y+k)/(x-1)向上取整,再加上第二种交易需要的k次就是答案了。

#include<bits/stdc++.h>
#define ll long long
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;

int32_t main()
{
    IOS;
    int t;
    cin>>t;
    while(t--)
    {
        ll x,y,k;
        cin>>x>>y>>k;
        ll need=k*y+k;
        ll ans=(need-1)/(x-1)+k;
        if((need-1)%(x-1)) ans++;
        cout<<ans<<endl;
    }
}

B题
贪心

题意为给定一个长度为n的数列,有一部分位置是锁定的,我们不能改变这些位置上数字的位置,而另一部分位置是不锁定的,我们可以任意交换这些位置上数字的位置。
现在希望你对这个数列上不锁定位置上的数字重新排列,使得这个数列的前缀和数组中,负数的最大下标最小。输出任意一种构造方式。

这里前缀和数组中负数的最大下标最小,那么对于某一个固定下标的前缀和,我们肯定希望前面构造的数字都尽可能大,这个贪心对于每一个固定下标都是相同的。因此我们直接把所有不锁定位置上的数字,按照从大到小的顺序重新排一遍就可。

#include<bits/stdc++.h>
#define ll long long
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;

vector<int>num;
int n;
int cas[107];

int32_t main()
{
    IOS;
    int t;
    cin>>t;
    while(t--)
    {
        cin>>n;
        num.clear();
        num.resize(n);
        deque<int>Q;//用于存储不锁定位置上的数字,排序后进行后续构造操作
        for(int i=0;i<n;i++) cin>>num[i];
        for(int i=0;i<n;i++)
        {
            cin>>cas[i];
            if(!cas[i]) Q.push_back(num[i]);
        }
        sort(Q.begin(),Q.end());
        for(int i=0;i<n;i++)
        {
            if(!cas[i])//对不锁定位置,我们依次按照从大到小的顺序把所有数字放进去。
            {
                num[i]=Q[Q.size()-1];
                Q.pop_back();
            }
        }
        for(int i=0;i<n;i++) cout<<num[i]<<' ';
        cout<<endl;
    }
}

C题
贪心,整体思维

题意为有n个boss依次要击杀,一部分是简单boss一部分是困难boss。你和你的朋友交替击杀boss(朋友先手),
每次可以选择击杀1个或者2个boss,但是你的朋友自己无法击杀困难boss,当他需要击杀困难boss的时候,需要使用1次道具才能击杀。现在需要你求出你和朋友最优策略的情况下,朋友使用道具的最少次数。

由于朋友先手,因此第一个boss必然由朋友击杀,如果第一个就是困难boss的话,朋友就必须要使用一次道具。之后的问题就可以看作是自己先手了。
对于连续的x个困难boss来说,如果是自己先手的话,采取贪心的策略,自己每次都击杀2个,而朋友每次都击杀1个,那么击杀完这x个boss需要的最少道具次数就是x/3个。
这n-1(除了第一个)个boss可以看成若干段连续的困难boss,他们之间存在着1个或以上的简单boss,我们是否可以通过某种策略使得每一段连续的困难boss都是由自己先手开始击杀呢?
注意到如果自己和朋友如果都只能击杀1只boss的话,就会固定为朋友只能击杀奇数下标的boss,自己只能击杀偶数下标的boss,但是现在自己和朋友可以选择击杀2只boss,一旦选择击杀2只boss,自己和朋友对应的奇偶下标就交换了。通过相邻段连续困难boss之间的简单boss,我们可以通过选择击杀2只boss交换两个人的奇偶下标而保证下一段困难boss是由自己先手开始击杀。

由此得到结论,所需最少道具次数就是除了第一个boss外的n-1个boss,每个连续困难boss的数量除以3后累加,如果第一个boss是困难就再加1即可。

#include<bits/stdc++.h>
#define ll long long
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
const ll maxn=2e5+7;

ll num[maxn];
ll n;

int32_t main()
{
    IOS;
    int t;
    cin>>t;
    while(t--)
    {
        cin>>n;
        for(ll i=0;i<n;i++) cin>>num[i];
        ll ans=0;
        if(num[0]) ans++;//由于朋友是先手,因此第一个boss如果就是困难的那就必须要使用一次道具
        ll temp=0;
        for(ll i=1;i<n;i++)
        {
            while(i<n&&num[i]==1)//统计连续的困难boss有多少个
            {
                temp++;
                i++;
            }
            ans+=temp/3;//除3加到答案上并置零
            temp=0;
        }
        cout<<ans<<endl;
    }
}

D题
贪心,set和优先队列维护动态个点相邻间线段长度的最大值

题意为在一条x轴上,有若干个整数点位置上有垃圾,现在你需要把这些垃圾聚集到不超过2个点的位置上。每次操作你可以选择一个下标x,把x位置上的所有垃圾移动到x-1或者x+1的位置。你需要输出最少的操作次数。并且此题有q次改变初始垃圾情况的操作,每次改变会增加或者删除一个垃圾,你需要对每次改变后输出最少的操作次数。

先推个结论,如果我们是把所有垃圾都聚集到一个点上的话,最优的操作就是垃圾的最右侧位置和最左侧位置的距离。因为我们任意在这一个线段上取一个点作为我们最终的聚集点,左侧部分从最左侧依次向右移动,右侧部分从最右侧依次向左移动,这是最优的方案,刚好等于线段长度。如果我们选择的最终聚集点在线段外的位置,自己稿纸上画一下就知道需要更多的操作次数(高中数学基础不讲了)。
现在我们可以聚集到两个点上,那么也就是说我们可以把原来的线段去除某一对相邻垃圾之间的线段,剩下两个线段分别进行聚集操作,那么我们只要使得删除的这一条线段长度最大,就是最优的方案了。

这样问题就转化为了如何维护动态个点的相邻线段长度的最大值,这里使用set和优先队列来实现。这里的思考方式在于,我们只需要关注线段中的最大值,因此可以用优先队列来实现,但是优先队列不支持任意值的删除操作,我们只需要再开一个优先队列保存待删除的线段长度即可。
而在原本的图中插入点和删除点的操作,我们只需要知道原图中新加入点左右侧是否有垃圾,且他们的位置在哪就可以知道需要删除和增加哪些线段。

具体实现见代码.

#include<bits/stdc++.h>
#define ll long long
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;

int n,q;
set<ll>S;//集合S用于存储当前有哪些位置上有垃圾,用于计算实现下面两个优先队列的当前线段和待删除线段
priority_queue<ll>length_now,length_delete;
//两个优先队列,now存储当前的图上所有的相邻点之间的线段长度,delete为插入和删除点过程中产生的待删除线段

//由于我们只关注所有点的最左侧和最右侧的距离(set可计算),以及相邻点之间的线段长度中的最大值(优先队列的top()可以获得)

void insert(ll x)//增加点操作
{
    if(S.size())//增加点可能会造成线段的增加和减少
    {
        auto now=S.lower_bound(x);//用lower_bound找到集合S中大于x的第一个位置
        if(now==S.begin()) length_now.push(*now-x);//如果大于x的第一个位置就是最小的点了,那加入的点是在目前的最左侧,只增加了*now-x这一条线段
        else//如果大于x的第一个位置不是最小的点
        {
            if(now==S.end())//如果大于x的第一个位置是集合的末尾,代表加入的点在最右侧,对now--操作变成之前最大点的位置,只增加了x-*now这一条线段
            {
                now--;
                length_now.push(x-*now);
            }
            else//如果不是末尾,则代表新加入的点是在两个点的中间
            {
                ll temp=*now;//用temp临时记录右侧点的值,再对now--变为左侧点的位置
                now--;
                length_now.push(temp-x);//新增加了两条线段,分别与左右侧相邻点构成
                length_now.push(x-*now);
                length_delete.push(temp-*now);//原本左右侧相邻点构成的线段被删除
            }
        }
    }
    S.insert(x);
}

void erase(ll x)//同insert操作的思路
{
    S.erase(x);
    if(S.size())
    {
        auto now=S.lower_bound(x);
        if(now==S.begin()) length_delete.push(*now-x);
        else
        {
            if(now!=S.end())
            {
                ll temp=*now;
                now--;
                length_now.push(temp-*now);
                length_delete.push(temp-x);
                length_delete.push(x-*now);
            }
            else
            {
                now--;
                length_delete.push(x-*now);
            }
        }
    }
}

void out()
{
    if(S.size()==0) cout<<0<<endl;//这里要特判一下集合S是否为空,否则下面的rbegin()-begin()的操作会出错
    else
    {
        while(length_delete.size()&&length_delete.top()==length_now.top())//我们只关注所有线段中最大的值,因此用优先队列存储即可
        {//把待删除的最大线段依次删去即可
            length_delete.pop();
            length_now.pop();
        }
        ll ans=*S.rbegin()-*S.begin();
        if(length_now.size()) cout<<ans-length_now.top()<<endl;
        else cout<<0<<endl;
    }
}

int32_t main()
{
    IOS;
    cin>>n>>q;
    for(ll i=0;i<n;i++)
    {
        ll x;
        cin>>x;
        insert(x);
    }
    out();
    for(ll i=0;i<q;i++)
    {
        ll ope,x;
        cin>>ope>>x;
        if(ope) insert(x);
        else erase(x);
        out();
    }
}
PostgreSQL的学习心得和知识总结(八十二)|深入理解PostgreSQL数据库SQL语句的词法解析和语法解析流程 postgresql 词法解析语法解析流程 阅读详情

相关推荐

从工创赛实战到开源:一个高鲁棒性智能物流视觉系统的构建与优化

本文分享了从工创赛实战中构建高鲁棒性智能物流视觉系统的完整经验。针对赛场复杂光线环境,详细阐述了摄像头选型、基于CLAHE和形态学梯度的抗干扰色环识别算法、卡尔曼滤波状态估计以及多线程串口通讯与任务调度等核心优化策略,旨在打造一个稳定可靠的视觉系统,并已将相关代码开源。

weixin_29046035的博客 318

Educational Codeforces Round 95 (Rated for Div. 2)

昨天本来想打一下,但是今天早上课很早,就没有打,只是看了看前三个题写了个代码,今天中午课结束交了一下都AC了。y1s1 A题第一次写就出来了,但是答案一直不对,最后结果是样例错了-。- A - Buying Torches 数学题,最终需要stick的数量是ky+kky+kky+k,然后直接求答案就行了。 #define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #pragma GCC optimize(2) #include<iostr

Fighting_Peter的博客 294

MOSFET开关损耗全面讲解:从原理到优化策略

深入剖析MOSFET开关损耗的产生机制,结合实际应用场景,讲解如何通过驱动设计和电路优化降低损耗,提升系统效率。重点关注mosfet在高频开关下的表现与热管理。

weixin_29476595的博客 1058

Educational Codeforces Round 95 (Rated for Div. 2)解题报告

Educational Codeforces Round 95 (Rated for Div. 2) A. Buying Torches 题目大意 111根棍子能换xxx根棍子,yyy根棍子能换一份煤,111根棍子和111份煤能组成一根火柴,初始时你只有一根棍子,问你最少最多少次交换可以获得kkk根火柴 解题思路 根据题目意思,我们至少要有kkk块煤,那么就需要kykyky根棍子,还需要另外的kkk根棍子与其组成kkk根火柴,设aaa为用棍子换棍子的次数,bbb表示用棍子换煤块的次数,则有: a(x−1)+

weixin_44211980的博客 302

汽车轮胎动平衡背后的秘密:如何用惯性主轴原理消除方向盘抖动

本文深入解析了汽车轮胎动平衡的核心原理,即利用惯性主轴原理消除高速行驶时的方向盘抖动。文章从方向盘抖动的现象出发,阐释了动不平衡产生的物理本质,并详细介绍了如何通过动平衡机测量、计算与校正,使轮胎-轮毂系统的实际旋转轴回归其惯性主轴,从而实现稳定运转。

grafana6viz的博客 346

SECS/GSM 测试工具 SecsExpress 的配置与实战应用

本文详细介绍了半导体设备通讯测试工具SecsExpress的配置与实战应用。作为专业的SECS/GSM协议调试工具,它能模拟Host与设备端进行双向测试,帮助工程师快速部署、验证通讯链路,并高效排查与RMS系统或真实设备间的联调问题,是提升半导体工厂设备集成与维护效率的利器。

yhn456789的博客 298

Educational Codeforces Round 95 (Rated for Div. 2) A. Buying Torches(思维)

题目大意就是开局一根小木棍,然后你可以与商人做生意,用一根木棍换X根木棍也可以用Y根木棍换1块煤,做一个火把需要一个木棍和一块煤,现在需要做K个火把,问总共最少要和好心的商人做多少次交易(MC?)。 很简单的,首先必须要拿到K个煤块,所以必须进行K次交换煤的交易(开局手上是没有煤块的)。然后我们需要从商人那交易到足够做火把和交易煤块用的木棍,即k + k * y - 1个木棍(开局自带一个,所以减1),看看总共要交易多少次。 void solve() { ll x,y,k;cin>>x&

欢迎光临 我的心 230

在Qt中集成VTK和PCL:实现数据可视化的完整指南

在现代软件开发中,数据可视化至关重要。将VTK(Visualization Toolkit)和PCL(Point Cloud Library)集成到Qt环境里,能为开发者提供强大的可视化解决方案。本文将深入讲解如何在Qt中读取PCL文件,展示VTK模型和PCL数据,适合想要在Qt项目中实现数据可视化的开发者。

轩宇的博客 916

Educational Codeforces Round 95 (Rated for Div. 2) C. Mortal Kombat Tower

人生中第一道初见一遍过的DP,感觉自己还是有进步的。

zeisenphael的博客 1106

SAP_PP模块中MRP中信号灯简介

一、信号灯的作用二、常见的信号灯颜色及含义三、信号灯的来源四、常见场景示例示例1:物料满足所有需求示例2:生产订单已延迟示例3:缺料或未产生计划订单五、相关事务码参考六、如何应对红色或黄色信号灯?七、前台操作说明在 SAP PP 模块中,**MRP(物料需求计划)运行结果中的“信号灯”是一种非常直观的可视化提示工具,用于帮助用户快速识别物料计划是否存在异常或需要关注的问题。这些信号灯通常出现在MD04(库存/需求清单)、MD05(单物料MRP清单)、MD07(MRP列表)**等事务代码的界面中。

我小时候很黑的博客 626

【STM32项目】基于STM32设计的震动马达超声波电机高频震动——高级定时器PWM互补输出带死区控制__资料编号3

实现高级定时器互补输出带死区控制,实现震动/超声波电机/马达,高频震动。使用 STM32F103 芯片输出两路互补 PWM,并带有死区和刹车控制功能。定时器 1 通道 1 及其互补通道输出PWM,且带死区控。当定时器 1 的刹车输入引脚被拉高时,产生刹车时间,即定时器 8 停止输出 PWM。当刹车输入引脚被拉高时,通道 1 和通道 2 将从有波形输入状态转换成无效电平状态。

嵌入式阿齐Archie 6742

Educational Codeforces Round 95 (Rated for Div. 2) G. Three Occurrences

线段树维护区间最小值和最小值的个数

Irving0323的博客 493

ESP32学习笔记03-日志打印

日志分为5个等级。

Car12 1415

[Educational Codeforces Round 54 (Rated for Div. 2)][D Edge Deletion]

http://codeforces.com/contest/1076/problem/D题目大意:给出一个无向图,要求只保留K条边,并且使尽可能多的点保持原来到点1的最短距离. 题解:先用堆优化的DIJ跑出最短路径树,然后利用bfs,从叶子处开始减边(因为减叶子的边只会影响一个点的最短路径,而从非叶子减边会影响多个点的最短路径) 1 #include<iostrea...

aiyuneng5167的博客 111

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

A. Find Divisible Educational Codeforces Round 57 (Rated for Div. 2)

A - Find Divisible 题意:英语翻译题,给你一个l,r区间,要求输出x,y,[x,y]在区间[l,r]中,y是x的倍数,原文中是这样写的 x divides y x被y整除 妈蛋,不用担心,x*2超出r边界,因为题上也说了,一定存在解,原文是这样的 妈蛋 题解:左边界l,右边界l*2,妈蛋。 代码: #include &l...

difubin1811的博客 303

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Educational Codeforces Round 83 (Rated for Div. 2) C. Adding Powers

传送门 题意: 思路: 每步可加kik^iki,也可以跳过不加,看能否构成给定数组 数组中的0是不需要处理的 我们直接一步一步把数分解即可,看要用到的i是否够用,每个i只能用一次 做的过程: 假设k=9,有一个数是b[i]=93+94+959^3+9^4+9^593+94+95 int l=0;//要用的幂次 while(1){ while(b[i]%k==0){ b[...

_Alexander的博客 2825

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Educational Codeforces Round 48 (Rated for Div. 2) D 1016D Vasya And The Matrix (构造)

&#13; D. Vasya And The Matrix&#13; time limit per test&#13; 2 seconds&#13; memory limit per test&#13; 256 megabytes&#13; input&#13; standard input&#13; output&#13; standard output&#13; Now ...

ACMerszl的博客 135

Codeforces Global Round 8 A-D

A:显然 交替加 增大最快 #include <bits/stdc++.h> using namespace std; typedef long long ll; #define ls (o<<1) #define rs (o<<1|1) #define pb push_back const double PI= acos(-1.0); const int M = 1e5+7; /* int head[M],cnt=1; void init(){cnt=1,memse

bjfu170203101的博客 358

Educational Codeforces Round 95 (Rated for Div. 2)补题

题目:D. Trash Problem 分析: 用set维护元素(将线性表的增删操作由O(n)优化成O(log(n))),用multiset维护差分. 学习迭代器相关函数。(prev, next) 注意点:multiset的erase(x)表示删除所有为x的值,erase(it)删除迭代器指向的单个元素。 代码: #include <bits/stdc++.h> using namespace std; typedef long long ll; //typedef __int128 lll;

玛珈山大萌新 273

CF1418A Buying Torches

文章目录CF1418A Buying Torches题目描述思路坑点代码总结 CF1418A Buying Torches 题目链接 题目描述 你要获得 k 个火把,最开始你有 1 根木棒。一个木棒和一个煤炭可以合成一个火把,你也可以通过两种交易方式得到木棒或煤炭: 通过给商人 1 根木棒,获得 x 根木棒。 通过给商人 y 根木棒,获得 1 个煤炭。 求得到 k 个火把的最少交易次数。 思路 1.由题意得一根木棒可以向商人换x根木棍,所以每次换的木根数要减一,就是x-1; 2.由提意得一根加一个煤

m0_63328909的博客 329
上一篇: Codeforces Round #670 (Div. 2)A-D题解
下一篇: Codeforces Round #671 (Div. 2)A-E题解
StandNotAlone
博客等级 码龄7年 338粉丝 47原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值