codeforce#933 题解

E. Rudolf and k Bridges

题意不讲了,不如去题干看图。
传统dp,每个点有两个选择,那么建桥要么不建。需要注意的是在状态转移的时候,桥是有长度的,如果不建需要前d格中建桥花费最少的位置作为状态转移的初态。

#include <iostream>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <time.h>
#include <set>
#include <unordered_set>
#include <map>
#include <queue>#define IOS     ios::sync_with_stdio(0);cin.tie(0);
#define mem(A,B) memset(A,B,sizeof(A));
#define rep(index,start,end) for(int index = start;index < end; index ++)
#define drep(index,start,end) for(int index = start;index >= end; index --)using namespace std;typedef long long ll;const int maxn = 2e5+5;struct contianer {private:int step;int pos = 0;ll loop[maxn];multiset<ll> store;public:contianer(int step):step(step) {}void add(ll x) {int now = pos % step;// need to removeif (pos >= step) {store.erase(store.find(loop[now]));}loop[now] = x;store.insert(x);pos ++;}/*** get min number*/ll get() {return *store.begin();}void setStep(int s);void clear();
};void contianer::setStep(int s) {step = s;
}void contianer::clear() {store.clear();pos = 0;
}ll sum[128];
int store[maxn];
ll dp[maxn][2];
int main() {IOSint t;cin>>t;while(t--) {int n,m,k,d;cin>>n>>m>>k>>d;contianer heap(d);sum[0] = 0LL;// input and dprep(_,0,n) {// inputrep(i,0,m) cin>>store[i];// initheap.clear();heap.add(store[0] + 1);dp[0][0] = dp[0][1] = store[0] + 1;// dprep(i,1,m-1) {ll min_cost = heap.get();dp[i][0] = min_cost;dp[i][1] = min(dp[i-1][0], min_cost) + store[i] + 1;
//                cout<<"dp["<<i<<"][0]:"<<dp[i][0]<<" dp["<<i<<"][1]:"<<dp[i][1]<<endl;heap.add(dp[i][1]);}// costsum[_ + 1] = min(dp[m-2][1], dp[m-2][0]) + 1LL;
//            cout<<sum[_+1]<<endl;}// pre sumrep(i,1,n+1) sum[i] += sum[i-1];// the k minll ans = sum[k] - sum[0];rep(i,k+1,n+1) {ans = min(ans, sum[i] - sum[i-k]);}// coutcout<<ans<<endl;}return 0;
}

F. Rudolf and Imbalance

求两数和的plus版本。给出数组a,现在要分别从d和f挑选一个数相加后放入a,使得所有 a i + 1 − a i a_{i+1} - a_i ai+1ai中最大值尽可能小。
显然,我们只要找到在没有挑选插入前 a i + 1 − a i a_{i+1} - a_i ai+1ai的最大值以及 i i i的值,然后构造 a i + 1 > d + f > a i a_{i+1} > d+f > a_i ai+1>d+f>ai,就可以破坏最大值。且 d + f = a i + 1 + a i 2 d+f = \frac {a_{i+1} + a_i}{2} d+f=2ai+1+ai时,能将最大值分割的尽可能小。
其中,如果最大值和第二大值一样,那么无论怎么分割都改变不了最大值,可以直接输出。
至于怎么让 d + f d+f d+f尽可能靠近中点就不细说了,固定d然后二分搜索f。这里我脑干缺失写了个int target = abs(aim - commonA);我是真的睿智

#include <iostream>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <time.h>
#include <set>
#include <map>
#include <queue>#define IOS     ios::sync_with_stdio(0);cin.tie(0);
#define mem(A,B) memset(A,B,sizeof(A));
#define rep(index,start,end) for(int index = start;index < end; index ++)
#define drep(index,start,end) for(int index = start;index >= end; index --)using namespace std;typedef long long ll;const int maxn = 2e5+5;struct record{int val;int ind;
};int store[maxn/2];
record dif[maxn/2];
int d[maxn], f[maxn];
bool cmp(const record& a, const record& b) {return a.val < b.val;
}
int abs(int a) {if (a<0) return -a;else return a;
}
int main() {IOSint t;cin>>t;while(t--) {int n,m,k;cin>>n>>m>>k;int pos = 0;cin>>store[0];rep(i,1,n) {cin>>store[i];dif[pos].ind = i;dif[pos ++].val = store[i] - store[i-1];}sort(dif, dif+pos,cmp);
//        rep(i,0,pos) cout<<dif[i].val<<endl;int len_d , len_f;if (m < k) {rep(i,0,m) cin>>d[i];sort(d, d+m);len_d = m;rep(i,0,k) cin>>f[i];sort(f, f+k);len_f = k;} else {rep(i,0,m) cin>>f[i];sort(f,f+m);len_f = m;rep(i,0,k) cin>>d[i];sort(d,d+k);len_d = k;}if (pos > 2 && dif[pos-1].val == dif[pos-2].val) {cout<<dif[pos-1].val<<endl;continue;}int sup = store[dif[pos-1].ind];int inf = store[dif[pos-1].ind - 1];int aim = inf + (sup - inf)/2;int minn = dif[pos-1].val;rep(i,0,len_d) {int commonA = d[i];if (commonA >= sup) break;int target = aim - commonA;
//            cout<<"d[i]:"<<d[i]<<" target:"<<target<<endl;auto it = upper_bound(f, f+len_f-1, target);
//            cout<<"it:"<<it<<endl;int commonB = *it;
//            cout<<"find:"<<commonB<<endl;int num = commonA + commonB;if (inf<num && num<sup)minn = min(minn, max(sup - num ,num - inf));if (it != f) {commonB = *(it-1);num = commonA + commonB;if (inf<num && num<sup)minn = min(minn, max(sup - num ,num - inf));}}/*if (d[0] + f[0] < store[0]) {aim = store[0];rep(i,0,len_d) {int commonA = d[i];if (commonA >= aim) break;int target = abs(aim - commonA);auto it = lower_bound(f, f+len_f-1, target-1);int commonB = *it;cout<<"commonA:"<<commonA<<" commonB:"<<commonB<<" target:"<<target<<endl;int num = commonA + commonB;if (num < store[0])minn = min(minn, store[0] - num);if (it != f) {commonB = *(it-1);num = commonA + commonB;if (num < store[0])minn = min(minn, store[0] - num);}}}aim = store[n-1];if (d[len_d-1] + f[len_f-1] > aim)rep(i,0,len_d) {int commonA = d[i];int target = abs(aim - commonA);auto it = upper_bound(f, f+len_f-1, target+1);int commonB = *it;int num = commonA + commonB;if (num > aim) {minn = min(minn, num - aim);}if(it == f) break;}*/cout<<max(minn, pos>=2? dif[pos-2].val : 0)<<endl;}return 0;
}

G. Rudolf and Subway

很好的图论使我小脑萎缩
边染色,求A->B最少经过几种颜色。其中相同颜色的边一定构成连通图。
机智如我并没有按照题解中加边的思路,而是采用合并点的方式,从颜色的维度处理。将相同颜色的边视为从同一个点出发(因为相同颜色内移动不会影响结果,只有移动到新的颜色上才会影响结果),从而将问题转化为最短路。采用bfs那么首先经过的颜色一定是最短路,从而可以作为优化的条件。
此外由于是边染色,所有可能一个点会被多个颜色所合并。如果在颜色A的合并点里走到了点v,同时v又连接B、C等颜色的边,虽然后续B、C颜色的合并也会重新遍历v的边,但是由于bfs的特性此时的遍历不会影响已经过的颜色A,也不会加入新的颜色(因为v涉及的所有颜色都在颜色A的合并点中加入到了队列),所以图中的每个点只需要访问一次,不需要重复访问。
没有这个优化会T 嘤嘤嘤

#include <iostream>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <time.h>
#include <set>
#include <map>
#include <queue>#define IOS     ios::sync_with_stdio(0);cin.tie(0);
#define mem(A,B) memset(A,B,sizeof(A));
#define rep(index,start,end) for(int index = start;index < end; index ++)
#define drep(index,start,end) for(int index = start;index >= end; index --)using namespace std;typedef long long ll;const int maxn = 2e5+5;struct node{int to;int color;
};queue<int> Q;
bool vis[maxn],visNode[maxn];
int dis[maxn];
set<int> colors;
set<int> colorSet[maxn];
vector<node> adj[maxn];
int main() {IOScout.tie(0);int t;cin>>t;while(t--) {for(auto it=colors.begin();it!=colors.end();it++){vis[*it] = false;colorSet[*it].clear();}colors.clear();int n,m;cin>>n>>m;rep(i,0,n+1) {adj[i].clear();visNode[i] = false;}rep(i,0,m) {int commonA,commonB,color;cin>>commonA>>commonB>>color;adj[commonA].push_back({commonB, color});adj[commonB].push_back({commonA, color});colorSet[color].insert(commonA);colorSet[color].insert(commonB);colors.insert(color);}int commonA,commonB;cin>>commonA>>commonB;if (commonA==commonB) {cout<<0<<endl;continue;}for(auto it=colors.begin();it!=colors.end();it++)dis[*it] = INT_MAX;visNode[commonA] = true;rep(i,0,adj[commonA].size()) {node edge = adj[commonA][i];if (!vis[edge.color]) {Q.push(edge.color);
//                cout<<"push color:"<<edge.color<<endl;dis[edge.color] = 1;vis[edge.color] = true;}}while(!Q.empty()) {int now = Q.front();
//            cout<<"color:"<<now<<" dis:"<<dis[now]<<endl;Q.pop();for(int v : colorSet[now]) {if (visNode[v]) continue;visNode[v] = true;int len = adj[v].size();rep(i,0,len) {node next = adj[v][i];int next_color = next.color;if (vis[next_color] || visNode[next.to]) continue;dis[next_color] = dis[now]+1;Q.push(next_color);vis[next_color] = true;}}}int ans = INT_MAX;rep(i,0,adj[commonB].size()) {node edge =adj[commonB][i];int des_color = edge.color;ans = min(ans, dis[des_color]);}cout<<ans<<endl;}return 0;
}

官方题解则是通过加边的方法传送门
请添加图片描述将染色边转化为一个新的染色节点连接到原有边的端点。可能这样画体现不出这个方法精妙之处。请添加图片描述点多了就能看出来,这样形成一个星形的连接,相同颜色的点之间移动都只需要经过两条边。仍然还是bfs,只不过由于边多加了,所以需要最终结果/2

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

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

相关文章

深度学习论文: MobileNetV4 - Universal Models for the Mobile Ecosystem及其PyTorch实现

深度学习论文: MobileNetV4 - Universal Models for the Mobile Ecosystem及其PyTorch实现 MobileNetV4 - Universal Models for the Mobile Ecosystem PDF: https://arxiv.org/pdf/2404.10518.pdf PyTorch代码: https://github.com/shanglianlm0525/CvPytorch PyTorch代码: ht…

swagger xss漏洞复现

swagger xss漏洞复现 文章目录 swagger xss漏洞复现漏洞介绍影响版本实现原理漏洞复现修复建议: 漏洞介绍 Swagger UI 有一个有趣的功能&#xff0c;允许您提供 API 规范的 URL - 一个 yaml 或 json 文件&#xff0c;将被获取并显示给用户 根本原因非常简单 - 一个过时的库Dom…

高级控件5-RecyclerView

与ViewPager类似的一个滑动的高级控件是RecyclerView&#xff0c;使用更加灵活。 第1步&#xff1a;添加依赖 打开mvn官网&#xff0c;检索recyclerview&#xff0c;选择使用人数较多的版本&#xff0c;复制依赖&#xff0c;放入项目中即可 快捷方法&#xff08;复制下面的代…

科普:PD协议、QC协议、三星AFC、华为SCP是什么,怎么获取这些协议及协议通讯原理

PD协议是什么 PD协议是由 USB-IF 组织制定的一种快速充电规范&#xff0c;它一般使用Type-C接口&#xff0c;所以常见的Type-C接口充电器一般都是支持PD协议。 USB Power Delivery(USB PD)是目前主流的快充协议之一&#xff0c;USB PD 通过Type-C电缆和连接器增加电力输送&…

【Unity动画系统】动画基本原理与Avater骨骼复用

动画基本原理 动画片段文件是一个描述物体变化状态的文本文件 在Unity中创建的资源文件大多都是YAML语言编写的文本文件 Curves表示一种变化状态&#xff0c;为空的话则没有记录任何内容 位置变化后的旋转变化状态&#xff1a; 动画文件里的Path名字要相同才能播放相同的动画 …

uniapp制作分页查询功能

效果 代码 标签中 <uni-pagination change"pageChanged" :current"pageIndex" :pageSize"pageSize" :total"pageTotle" class"pagination" /> data中 pageIndex: 1, //分页器页码 pageSize: 10, //分页器每页显示…

[笔试训练](九)

目录 025&#xff1a;添加逗号 026&#xff1a;跳台阶 027&#xff1a;扑克牌顺子 025&#xff1a;添加逗号 添加逗号_牛客题霸_牛客网 (nowcoder.com) 题目&#xff1a; 题解&#xff1a; 将输入的数字&#xff0c;每次模上10&#xff0c;从个位开始取每一位数&#xff…

[C++ QT项目实战]----C++ QT系统登陆界面设计

前言 在C QT项目开发过程中&#xff0c;设计系统登录界面可以使用QT框架来实现。以下是一个简单的系统登录界面设计示例&#xff1a; 创建登录界面UI&#xff1a;可以使用QT Designer来设计登录界面的UI&#xff0c;包括用户名输入框、密码输入框、登录按钮等。在QT Designer中…

Centos8操作系统安装mysql5.7版本以及报错解决

目录 一、卸载MySql 1.首先查看已安装的mysql 2.逐个或者执行一下命令统一卸载掉 注意&#xff1a; 3. 卸载其他相关文件 二、安装MySql 1.安装mysql的rpm源 2.安装MySql 如果遇到以下错误&#xff1a; 问题一: 解决方法&#xff1a; 问题二、 解决方法&#xff1…

C语言面试题之相交链表

相交链表 实例要求 1、给定两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。2、如果两个链表不存在相交节点&#xff0c;返回 null 。示例&#xff1a; 实例分析 可以使用两种方法&#xff1a;哈希表方法和双指针方法。哈希表方法…

【分布式 | 第四篇】限流算法实现方案

文章目录 4.限流算法4.1计算器4.2漏桶算法4.3令牌桶限流 4.限流算法 4.1计算器 计数器比较简单粗暴&#xff0c;比如我们要限制1s能够通过的请求数实现的思路就是从第一个请求进来开始计时&#xff0c;在接下来的1s内&#xff0c;每个请求进来请求数就1&#xff0c;超过最大请…

删除二叉搜索树中的节点

题目链接 删除二叉搜索树中的节点 题目描述 注意点 节点值唯一root 是合法的二叉搜索树节点数的范围 [0, 10000] 解答思路 可以根据二叉搜索树的性质找到要删除的节点&#xff0c;关键是删除节点后怎么重新构建成一棵新的二叉搜索树首先要找到的是删除节点node的父节点nod…

微信小程序:9.小程序配置

全局配置文件 小程序根目录下的app.json文件是小程序的全局配置文件。 常用的配置文件如下: pages 记录当前小程序所有的页面存放路径信息 window 全局设置小程序窗口外观 tabBar 设置小程序底部的tabBar效果 style 是否启用新版style 小程序窗口的组成部分 了解windo节点常…

场景文本检测识别学习 day07(BERT论文精读)

BERT 在CV领域&#xff0c;可以通过训练一个大的CNN模型作为预训练模型&#xff0c;来帮助其他任务提高各自模型的性能&#xff0c;但是在NLP领域&#xff0c;没有这样的模型&#xff0c;而BERT的提出&#xff0c;解决了这个问题BERT和GPT、ELMO的区别&#xff1a; BERT是用来…

微信收款码0.2费率开通

很多人想申请低手续费率的收款码不知从何下手&#xff0c;在参考了大量博客教学之后&#xff0c;终于搞懂了详细流程以及注意事项。在此记录一下。我申请的是一个只需要0.2%费率的微信收款码&#xff0c;申请时间是2022年2月12日。申请之前只需要准备营业执照和法人身份z&#…

【iconv】Linux c++ 中文字符串转十六进制 GBK 编码/内码

文章目录 问题描述c 代码CMakeLists.txt参考链接 问题描述 Linux 系统默认使用的是 UTF-8 编码&#xff0c;并且 c 中没有标准库可以直接将中文字符转为 GBK 编码/内码。因此需要借助 iconv 库来实现。 在实现代码之前&#xff0c;可以在一下在线工具网站进行中文字符到各个编…

​可视化大屏C位图:园区鸟瞰

将园区鸟瞰图作为可视化大屏设计的焦点图有以下几个好处&#xff1a; 提供全局视图&#xff1a;园区鸟瞰图可以展示整个园区的布局和结构&#xff0c;提供全局视图。这对于大型园区或复杂的场所来说尤为重要&#xff0c;用户可以一目了然地了解整个园区的规模、分布和关联关系…

使用新版ESLint,搭配Prettier使用的配置方式

概述 ESLint重大更新(9.0.0版本)后,将不再支持非扁平化配置文件,并且移除了与Prettier冲突的规则,也就是说与Prettier搭配使用,不再需要使用插件“eslint-config-prettier”来处理冲突问题。 注:使用新版的前提条件是Node.js版本必须是18.18.0、20.9.0,或者是>=21.1…

ESP-IDF编译系统详解(1)

接前一篇文章&#xff1a;VSCode ESP-IDF安装与配置全过程 本文内容主要参考&#xff1a; 《ESP32-C3物联网工程开发实战》 —— 乐鑫科技 编著 特此致谢&#xff01; 前文已经详述了ESP-IDF开发环境的搭建&#xff0c;包括ESP-IDF的下载与安装完整流程&#xff0c;以及VSCo…

怎么排查K8S容器当中的Java程序内存泄露问题

今天早上发现生产线其中的一个服务在凌晨的时候突然重启了&#xff0c;内存突然从1G升到1.8G&#xff0c;CPU使用量从0.1升到了0.28&#xff0c;说明在这个时间点&#xff0c;内存突增达到了限额以上&#xff0c;服务重启了。因为这个服务布署了多节点&#xff0c;这次重启对业…