Codeforces Round #703 (Div. 2) A、B、D、E题解
写在前边
链接:Codeforces Round #703 (Div. 2)
这次的交互题是真不会做。
A. Shifting Stacks
链接:A题链接
题目大意:
有\(n\)摞高度分别为\(h_i\)的山,现在我们可以从每次从第\(i\)座山移动高度为\(1\)的移到\(i + 1\)座山上,问是否可以形成一个严格单调递增的山脉。
思路:
贪心的想我们一直挪山,让第一座山高度为\(0\),第二座山高度为\(1\),第三座山高度为为\(2\),依次类推就可以了,这样形成\(1,2,3,...,i\)座山的总需要的高度就是\(need = \cfrac{i(i-1)}{2}\), 所以我们对于枚举到的每一座山只需要判断目前拥有的高度\(\sum\limits_{k = 1}^i h[k]\)是否能构造出\(need\)即可,即\(\sum\limits_{k = 1}^i h[k] > \cfrac{i(i-1)}{2}\)
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <map>
#include <cstring>
//#pragma GCC optimize(2)
//#pragma GCC optimize(3,"Ofast","inline")
using namespace std;
#define Inf 0x3f3f3f3f
#define PII pair<int, int>
#define P2LL pair<long long, long long>
#define endl '\n'
typedef long long LL;
typedef unsigned long long ULL;
typedef vector<long long> VLL;
typedef vector<int> VI;
const int Mod = 10000007;
const int N = 110;
LL h[N];
void solve() {
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++) scanf("%lld", &h[i]);
LL sum = 0, need = 0;
for (int i = 0; i < n; i++) {
need += i;
sum += h[i];
if (sum < need) {
puts("NO");
return;
}
}
puts("YES");
}
int main()
{
//ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int t;
scanf("%d", &t);
while (t--) {
solve();
}
return 0;
}
B. Eastern Exhibition
链接:B题链接
题目大意:
给定一堆\((x,y)\),两点距离定义为\(|x_2 - x_1| + |x_2 - x_1|\),现在需要选取有多少个点到每个点之和最小。
思路:
首先想到\(|x_2 - x_1|\)与\(|x_2 - x_1|\)坐标的距离互不影响,于是就可以转化成先求一维,然后利用乘法原理相乘就是结果。
对于一维,就是经典的货仓选址了,排个序,对于奇数个点,那么就中位数唯一,如果是偶数,那么可以选择两个中位数以及之间任意位置即可,即\([\cfrac{n}{2}, \cfrac{n}{2} + 1]\)
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <map>
#include <cstring>
//#pragma GCC optimize(2)
//#pragma GCC optimize(3,"Ofast","inline")
using namespace std;
#define Inf 0x3f3f3f3f
#define PII pair<int, int>
#define P2LL pair<long long, long long>
#define endl '\n'
typedef long long LL;
typedef unsigned long long ULL;
typedef vector<long long> VLL;
typedef vector<int> VI;
const int Mod = 10000007;
const int N = 1010;
int x[N], y[N];
void solve() {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d%d", &x[i], &y[i]);
}
sort(x + 1, x + n + 1);
sort(y + 1, y + n + 1);
if (n & 1) puts("1");
else {
int calx = x[n / 2 + 1] - x[n / 2] + 1, caly = y[n / 2 + 1] - y[n / 2] + 1;
printf("%lld\n", (LL) calx * caly);
}
}
int main()
{
//ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int t;
scanf("%d", &t);
while (t--) {
solve();
}
return 0;
}
D. Max Median
链接:D题链接
题目大意:
给定一个数组长度为\(n\)的数组\(a\),求长度为至少\(k\)的子数组的最大中位数。
思路:
参考博客:随处可见的阿宅
枚举一个最大的中位数明显可以用二分来优化,然后再检查其合理性,二分枚举一个\(x\),检查其合理性即检查它是否为中位数的时候可以有一个技巧,即构造一个序列,让\(\geq x\)的数
为\(1\),让\(\leq x\)的数为\(-1\),那么这样来说,如果某一长度至少为\(k\)子段和大于\(0\),那么\(x\)就是这个子段的中位数,很神奇,那么这里可以用前缀和优化,剩下的就是枚举长度至少为\(k\)的前缀和了,所以剩下的任务就是找一个\(i \geq k\)以及\(j \in [1, i - k]\),且满足\(s[i] - s[j] > 0\),而对于\(s[j]\)我们仅需要维护那个最小的前缀即可。
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <map>
#include <cstring>
//#pragma GCC optimize(2)
//#pragma GCC optimize(3,"Ofast","inline")
using namespace std;
#define Inf 0x3f3f3f3f
#define PII pair<int, int>
#define P2LL pair<long long, long long>
#define endl '\n'
typedef long long LL;
typedef unsigned long long ULL;
typedef vector<long long> VLL;
typedef vector<int> VI;
const int Mod = 10000007;
const int N = 2e5 + 10;
int a[N], b[N], minpref[N];
int n, k;
bool check(int x) {
for (int i = 1; i <= n; i++) b[i] = (a[i] >= x ? 1 : -1);
for (int i = 1; i <= n; i++) b[i] += b[i - 1];
for (int i = 1; i <= n; i++) minpref[i] = min(minpref[i - 1], b[i]);
for (int i = k; i <= n; i++) {
if (b[i] - minpref[i - k] > 0) return true;
}
return false;
}
void solve() {
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
int l = 1, r = n + 1;
while (l < r) {
int mid = l + r + 1 >> 1;
if (check(mid)) l = mid;
else r = mid - 1;
}
printf("%d\n", l);
}
int main()
{
//ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
solve();
return 0;
}
E - Paired Payment
链接:E题链接
题目大意:
最短路问题,只不过是一次只能走两步,不能一次一步走,比如a->b->c,那么就是a->c,花费是\((w_{ab} + w_{bc})^2\)
思路:
参考博客:随处可见的阿宅
两天了,终于悟了,其实暴力跑单源最短路就可以,比如从\(a->b->c\) (\(a, b, c\)指点集,不是具体的点),那么就是从\(a\)搜到最短的\(b\),然后再从\(b\)搜到最短的\(c\),就是两重循环,然后看大佬一个很重要的优化就是,当\(b\)作为中间点的时候,我们可以维护一个\(a->b\)的最短路径,这样由于边权最大就是\(50\),所以最坏情况下更新次数也不会超过\(50\)的,那么这题就终于这么过了。
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <map>
#include <cstring>
#include <queue>
//#pragma GCC optimize(2)
//#pragma GCC optimize(3,"Ofast","inline")
using namespace std;
#define Inf 0x3f3f3f3f
#define PII pair<int, int>
#define P2LL pair<long long, long long>
#define endl '\n'
typedef long long LL;
typedef unsigned long long ULL;
typedef vector<long long> VLL;
typedef vector<int> VI;
const int Mod = 10000007;
const int N = 1E5 + 10, M = 4 * N;
int h[N], e[M], ne[M], w[M], idx;
int dist[N], mindist[N];
bool st[N];
void add(int a, int b, int c) {
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}
void Dijkstra() {
priority_queue<PII, vector<PII>, greater<PII> > heap;
heap.push({0, 1});
memset(dist, 0x3f, sizeof dist), memset(mindist, 0x3f, sizeof mindist);
dist[1] = 0;
while (heap.size()) {
auto t = heap.top();
heap.pop();
int var = t.second, cost = t.first;
if (st[var]) continue;
st[var] = true;
for (int i = h[var]; i != -1; i = ne[i]) {
int var1 = e[i], cost1 = w[i];
if (mindist[var1] > cost1) {
for (int j = h[var1]; j != -1; j = ne[j]) {
int var2 = e[j], cost2 = w[j];
if (dist[var2] > (cost2 + cost1) * (cost2 + cost1) + cost) {
dist[var2] = (cost2 + cost1) * (cost2 + cost1) + cost;
heap.push({dist[var2], var2});
}
}
mindist[var1] = cost1;
}
}
}
}
void solve() {
int n, m;
scanf("%d%d", &n, &m);
memset(h, -1, sizeof h);
for (int i = 1; i <= m; i++) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
add(a, b, c), add(b, a, c);
}
Dijkstra();
for (int i = 1; i <= n; i++) {
if (dist[i] == 0x3f3f3f3f) printf("%d ", -1);
else printf("%d ", dist[i]);
}
}
int main()
{
//ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
solve();
return 0;
}
Codeforces Round #703 (Div. 2) A、B、D、E题解的更多相关文章
- Codeforces Round #524 (Div. 2)(前三题题解)
这场比赛手速场+数学场,像我这样读题都读不大懂的蒟蒻表示呵呵呵. 第四题搞了半天,大概想出来了,但来不及(中途家里网炸了)查错,于是我交了两次丢了100分.幸亏这次没有掉rating. 比赛传送门:h ...
- Codeforces Round #703 (Div. 2)__ B. Eastern Exhibition__ 纯纯的思维
原题链接https://codeforces.com/contest/1486/problem/B 题目 解题思路 这是个思维题, 算是货仓选址的变式, 想要到达各个点距离最小,我们的目标可以化为先 ...
- Codeforces Round #703 (Div. 2) (A~E)
A. Shifting Stacks 题目链接 点我跳转 题目大意 给定 \(N\) 个土堆,第 \(i\) 个土堆有 \(Ai\) 个木块 你可以将第 \(i\) 个土堆的木块转移至第 \(i + ...
- Codeforces Round #796 (Div. 2)(A~E题题解)
文章目录 原题链接: A.Cirno's Perfect Bitmasks Classroom 思路 代码 B.Patchouli's Magical Talisman 思路 代码 C.Manipul ...
- Codeforces Round #530 (Div. 2) (前三题题解)
总评 今天是个上分的好日子,可惜12:30修仙场并没有打... A. Snowball(小模拟) 我上来还以为直接能O(1)算出来没想到还能小于等于0的时候变成0,那么只能小模拟了.从最高的地方进行高 ...
- Codeforces Round #646 (Div. 2)【B. Subsequence Hate题解】
具体思路已经在代码注释中给出,这里不再赘述. #include<iostream> #include<algorithm> using namespace std; int t ...
- Codeforces Round #631 (Div. 1) B. Dreamoon Likes Sequences 题解(思维+求贡献)
题目链接 题目大意 让你构造一个严格单调上升的数组a满足\(1<=a_1<a_2<....a_n<=d\) 而且要使得这个数组的异或前缀和也满足严格单调上升,求有多少个满足条件 ...
- Codeforces Round #674 (Div. 3) F. Number of Subsequences 题解(dp)
题目链接 题目大意 给你一个长为d只包含字符'a','b','c','?' 的字符串,?可以变成a,b,c字符,假如有x个?字符,那么有\(3^x\)个字符串,求所有字符串种子序列包含多少个abc子序 ...
- Codeforces Round #672 (Div. 2) B. Rock and Lever题解(思维+位运算)
题目链接 题目大意 给你一个长为n(n<=1e5)的数组,让你求有多少对a[i]和a[j] (i!=j)满足a[i]&a[j]>a[i]^a[j] 题目思路 这些有关位运算的题目肯 ...
- Codeforces Round #665 (Div. 2) D. Maximum Distributed Tree 题解(贪心+易错)
题目链接 题目大意 给你一课树,要你给每一条边分权值,每条边的权值大于0,他们的乘积等于k,而且要使得n-1条边1的数量尽可能少,定义 f(u,v)为u到v的边权和求 \(\max \sum_{i=1 ...
随机推荐
- pandas取出包含某个值的所有行
pandas取出包含某个值的所有行df = df[df["from_account"].str.contains("fcwhx")] pandas取出不包含某个 ...
- 堆 Heap & 栈 Stack(.Net)【概念解析系列_3】【C# 基础】
〇.前言 本文主要围绕 .Net 框架中的托管堆(Heap,简称堆)和堆栈(Stack,简称栈)展开. .Net 程序在 CLR(Common Language Runtime 公共语言运行时)上运行 ...
- 青少年CTF平台 Web签到
题目说明 Web一星简单题,Web签到. 直接启动环境,等待30秒左右访问题目链接. 做题过程 进入后,题目好像没有告诉我们什么有用的信息, F12,看遍了题目源码,也没有发现flag,正当我怀疑这个 ...
- 简单搭建基本Prometheus监控系统
前言 适用场景:新手入门:内网离线部署,只是需要了解服务器基本情况,不需要告警系统. 需要准备的安装包: grafana的docker包(先在线下载,然后docker save保存镜像.如果没有doc ...
- 【Unity3D】运动模糊特效
1 运动模糊原理 开启混合(Blend)后,通过 Alpha 通道控制当前屏幕纹理与历史屏幕纹理进行混合,当有物体运动时,就会将当前位置的物体影像与历史位置的物体影像进行混合,从而实现运动模糊效果 ...
- 搞懂 Vue3 中的各种 ref:toRef,toRefs,isRef,unref...
在 Vue3 中,有许多与响应式相关的函数,例如 toRef.toRefs.isRef.unref 等等.合理地使用这些函数可以在实际开发中大大提高效率.本文将详细介绍这些函数的用法,让我们在实际开发 ...
- 4.2 C++ Boost 内存池管理库
Boost 库是一个由C/C++语言的开发者创建并更新维护的开源类库,其提供了许多功能强大的程序库和工具,用于开发高质量.可移植.高效的C应用程序.Boost库可以作为标准C库的后备,通常被称为准标准 ...
- 1.JDK的安装与卸载
1.卸载: 卸载或更改程序,找到相应的JDK程序,删除 2.安装: 官网下载JDK程序:jdk-8u25-windows-i586.exe 双击安装程序,同意协议,更改安装路径:C:\jdk1.8.0 ...
- SpringCloud搭建保姆级教程
一.搭建服务注册与发现中⼼ 使⽤Spring Cloud Netflix 中的 Eureka 搭建服务注册与发现中⼼ 1.创建SpringBoot应用添加依赖 1.spring web 2.eurek ...
- python url中文转码_python实现转换url编码的方法
python url中文转码_python实现转换url编码的方法 urllib.parse命令:url编码转换 >>> import urllib.parse >>&g ...