Codeforces Round #542 题解
Codeforces Round #542
abstract
I决策中的独立性,
II联通块染色板子
IIIVoronoi diagram O(N^2 logN)
VI环上距离分类讨论加取模,最值中的决定性元素
V代数构造
B
题意
2n个数排成一行,1..n各出现两次,两个人分别从1按顺序走到n(每个数只能被一个人路过),问他们两个人的距离和的最小值(两个数之间的距离等于他们位置(下标)值差)?
题解
将每个数的两个位置用pair存起来(eg : pos[1].x , pos[1].y)。
首先我们发现两个人的选择其实并不独立,如果一个人选择了一条路,另一个人的路也就确定了。其次我们发现每两个数之间的路径是相互独立的。
所以对于每一段 i to i+1 我们只要取min(abs(pos[i + 1].x - pos[i].x) + abs(pos[i + 1].y - pos[i].y), abs(pos[i + 1].x - pos[i].y) + abs(pos[i + 1].y - pos[i].x))即可。 最后求和
代码
//头文件省略
cin >> n;
rep(i, 1, 2 * n) {
int a;
cin >> a;
if (pos[a].x == 0)pos[a].x = i;
else pos[a].y = i;
}
ll ans = pos[1].x + pos[1].y - 2;;
rep(i, 1, n - 1)c[i] = min(abs(pos[i + 1].x - pos[i].x) + abs(pos[i + 1].y - pos[i].y), abs(pos[i + 1].x - pos[i].y) + abs(pos[i + 1].y - pos[i].x));
rep(i, 1, n-1)ans += c[i];
cout << ans;
C
题意
求网格图上联通块之间的最短距离平方。
sample input
5
1 1
5 5
00001
11111
00111
00110
00110
sample input
10
其中0代表陆地,1代表海洋
题解
直接跑一遍联通块染色,然后暴力O(n^4)就能过。
优化的方法是取边界,O(n^3)。
最优解是Voronoi diagram O(N^2 logN)
代码
#include<algorithm>
#include<iostream>
#include<sstream>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#include<math.h>
#include<stdio.h>
#include<vector>
#include<queue>
#include<string>
#include<ctime>
#include<stack>
#include<map>
#include<set>
#include<list>
using namespace std;
#define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
#define REP(i,j,k) for(int i = (int)j;i < (int)k;i ++)
#define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
#define debug(x) cerr<<#x<<" = "<<(x)<<endl
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define MD(x) x%=mod
#define FAST_IO ios_base::sync_with_stdio(false); cin.tie(nullptr)
#define precise(x) fixed << setprecision(x)
//#define x first
//#define y second
typedef double db;
typedef long long ll;
const int MAXN = 256;;
const int maxn = 2e5+2;
const int INF = 1e9;
const db eps = 1e-7;
const int mod = 1e9 + 7;
//a[maxn], b[maxn];
int A[maxn];
char mmp[55][55];
int color[55][55];
int n,m;
int dir[4][2] = { 0,1 ,1,0, 0,-1, -1,0 };
int colornum = 0;
void dfs(int x, int y) {
if (color[x][y])return;
color[x][y] = colornum;
rep(i, 0, 3) {
int dx = x + dir[i][0];
int dy = y + dir[i][1];
if (dx<1 || dx>n || dy<1 || dy>n)continue;
if(mmp[dx][dy]=='0')dfs(dx, dy);
}
}
void bfs(int x, int y) {
queue<pair<int, int> >Q;
Q.push({ x,y });
color[x][y] = colornum;
while (!Q.empty()) {
auto v = Q.front();
Q.pop();
rep(i, 0, 3) {
int dx = v.first + dir[i][0];
int dy = v.second + dir[i][1];
if (color[dx][dy])continue;
if (dx<1 || dx>n || dy<1 || dy>n)continue;
if (mmp[dx][dy] == '0')Q.push({ dx,dy }),color[dx][dy]=colornum;
}
}
}
int main() {
FAST_IO;
cin >> n;
int r1, c1, r2, c2;
cin >> r1 >> c1 >> r2 >> c2;
rep(i, 1, n)cin >> mmp[i] + 1;
rep(i, 1, n)rep(j, 1, n) if(mmp[i][j]=='0'){
if (!color[i][j]) {
colornum++;
bfs(i, j);
}
}
int ans = 1e9;
if (color[r1][c1] == color[r2][c2])ans = 0;
else {
rep(i, 1, n)rep(j, 1, n)if (color[i][j] == color[r1][c1]) {
rep(ii, 1, n)rep(jj, 1, n)if (color[ii][jj] == color[r2][c2]) {
ans = min(ans, (i - ii)*(i - ii) + (j - jj)*(j - jj));
}
}
}
cout << ans << endl;
cin >> n;
}
D
题意
有一个n个结点的环,每个结点上有一些糖果,每个糖果都有一个想要到达的结点,你现在从某个结点出发顺时针走,每次经过一个结点只能带一个糖果,问从某点出发最少走多少路程可以把所有糖果运送到它们想要到达的结点? 出发点取遍1到n。
题解
我们发现从某结点出发拿一个糖果,最坏情况下走一圈以后一定可以把它放好。而如果某节点有两颗糖果,那么至少要超过一圈才能放好。
所以 如果记所有结点中糖果数量最大值为mx,最多mx+1圈必定能全部送完。
而对一个结点来说,只有它的最后一个糖果想到达的结点决定了运完该点所有糖果总路程的长短,因此我们贪心地把路程最短的糖果留到最后拿即可。
于是问题就变成了环上求路程了,要用到取模,和分类讨论。(分类很不擅长,讨论了半天orz坑点:candy[now].size()==mx-1&&mx>1如果不加后面这个mx>1就会讨论根本没有糖果的情况,导致wa)
代码
//头文件省略
int n;
int a[maxn], b[maxn];
vector<int> candy[maxn];
int mindis[maxn];
int lastmin[maxn];
int main() {
FAST_IO;
int n, m;
cin >> n >> m;
rep(i, 1, n)mindis[i] = 1e9,lastmin[i]=0;
rep(i, 1, m) {
cin >> a[i] >> b[i];
candy[a[i]].push_back(b[i]);
mindis[a[i]] = min(mindis[a[i]], (b[i] - a[i]+n)%n);
}
int mx = 0;
rep(i, 1, n)mx = max(mx, (int)candy[i].size());
rep(i, 1, n) {
rep(j, 1, n) {
int now = (i - j+n)%n; if (now == 0)now = n;
if(candy[now].size()==mx)
lastmin[i] = max(lastmin[i],
(now - i + n) % n+mindis[now]);
else if(candy[now].size()==mx-1&&mx>1)
lastmin[i] = max(lastmin[i],
(now - i + n) % n + mindis[now]-n);
}
}
//rep(i, 1, n)cout << mindis[i] << ' '; cout << endl;
//rep(i, 1, n)cout << lastmin[i] << ' '; cout << endl;
rep(i, 1, n) {
cout <<n*(mx-1) + lastmin [i] << ' ';
}
cin >> n;
}
E
题意
构造题,给你一个问题,和一个错误算法,让你构造数据使得正确答案与错误代码答案相差k。
问题是有一个数列,a[i]<1e6,n<2e3;定义 f(l,r)=(sum[r]-sum[l-1])*(r-l+1),sum为前缀和,求max{f(l,r)} for l=1 to n, r=l to n;
错误代码是线性滑窗扫一遍,每次维护一个区间窗口,如果小于0就舍弃原区间,重新开一个新区间。如果和大于0就不停加数。
题解
代码很简单,构造很巧妙,证明很数学
考虑形如 -1 , x, x, x,...x,y的数列,共n个x,1个y都为正数(其中x都是1e6,为了满足原数列每个数<=1e6的条件),错误代码给出的解是(x*n+y)*(n+1);而正确答案应是(x*n+y-1)*(n+2)两者差为n*x+y-2 令x=1e6,n=k/x,y=k%x即可。(代数不好推了半天orz)
代码
//头文件省略
int k; cin >> k;
n = 1;
int S = -1;
int last = -1;
while (S-n+1<k) {
n++;
int delta = k-(S - n + 1) ;
if (delta <= 1e6) { last = delta; break; }
else S += 1e6;
}
cout << n << endl;
cout << -1 << ' ';
rep(i,1,n-2)cout<< 1000000 << ' ';
if (last != -1)cout << last << endl;
Codeforces Round #542 题解的更多相关文章
- Codeforces Round #542 [Alex Lopashev Thanks-Round] (Div. 2) 题解
Codeforces Round #542 [Alex Lopashev Thanks-Round] (Div. 2) 题目链接:https://codeforces.com/contest/1130 ...
- Codeforces Round 542 (Div. 2)
layout: post title: Codeforces Round 542 (Div. 2) author: "luowentaoaa" catalog: true tags ...
- Codeforces Round #556 题解
Codeforces Round #556 题解 Div.2 A Stock Arbitraging 傻逼题 Div.2 B Tiling Challenge 傻逼题 Div.1 A Prefix S ...
- Codeforces Round #569 题解
Codeforces Round #569 题解 CF1179A Valeriy and Deque 有一个双端队列,每次取队首两个值,将较小值移动到队尾,较大值位置不变.多组询问求第\(m\)次操作 ...
- Codeforces Round #557 题解【更完了】
Codeforces Round #557 题解 掉分快乐 CF1161A Hide and Seek Alice和Bob在玩捉♂迷♂藏,有\(n\)个格子,Bob会检查\(k\)次,第\(i\)次检 ...
- CFEducational Codeforces Round 66题解报告
CFEducational Codeforces Round 66题解报告 感觉丧失了唯一一次能在CF上超过wqy的机会QAQ A 不管 B 不能直接累计乘法打\(tag\),要直接跳 C 考虑二分第 ...
- Codeforces Round #542 (Div. 1) 题解
开学了住校了打不了深夜场 好难受啊QwQ A 显然对于每个起点,我们只需要贪心记录这个起点出发出去的糖果数量以及离自己最近的糖果 因为这个起点最后一次装载糖果一定是装载终点离自己最近的那个糖果 $ O ...
- Codeforces Round #542 [Alex Lopashev Thanks-Round] (Div. 1) 题解
A. Toy Train 时间限制:2 seconds 内存限制:256 megabytes 题意 有编号111~n(n≤5000)n(n\le 5000)n(n≤5000)的车站顺时针呈环排列,有m ...
- Codeforces Round #542(Div. 2) CDE 思维场
C https://codeforces.com/contest/1130/problem/C 题意 给你一个\(n*m\)(n,m<=50)的矩阵,每个格子代表海或者陆地,给出在陆地上的起点终 ...
随机推荐
- Lua中__index和__newindex实践
[具有默认值的table] 我们都知道,table中的任何字段的默认值都是nil,但是通过元表,我们可以很容易的修改这一规定,代码如下: function setDefault(tb, default ...
- 【MYSQL】MYSQL报错解决方法: Warning: (3719, "'utf8' is currently an alias for the character set UTF8MB3, but will be an alias for UTF8M B4 in a future release."
用python3.6.5创建mysql库时出现如下报错,虽然报错,但是数据库可以插入成功. D:\python3\lib\site-packages\pymysql\cursors.py:170: W ...
- ILMerge参考文档
ILMerge Michael BarnettResearch in Software Engineering (RiSE)Microsoft ResearchCopyright © Microsof ...
- springboot配置详解
springboot配置详解 Author:SimpleWu properteis文件属性参考大全 springboot默认加载配置 SpringBoot使用两种全局的配置文件,全局配置文件可以对一些 ...
- ==、Equals 、ReferenceEquals它们的异同
链接 string foobar = "foobar"; string foobar2 = new StringBuilder().Append("foo"). ...
- javaAPI实现elasticsearch5.5.2的聚合分析
https://blog.csdn.net/plei_yue/article/details/78452633
- 关于 永恒之蓝 和 MS17-010 补丁
[KB4012598]:http://www.catalog.update.microsoft.com/Search.aspx?q=KB4012598 适用于Windows XP 32位/64位/嵌入 ...
- sklearn交叉验证2-【老鱼学sklearn】
过拟合 过拟合相当于一个人只会读书,却不知如何利用知识进行变通. 相当于他把考试题目背得滚瓜烂熟,但一旦环境稍微有些变化,就死得很惨. 从图形上看,类似下图的最右图: 从数学公式上来看,这个曲线应该是 ...
- 一起学爬虫——使用Beautiful Soup爬取网页
要想学好爬虫,必须把基础打扎实,之前发布了两篇文章,分别是使用XPATH和requests爬取网页,今天的文章是学习Beautiful Soup并通过一个例子来实现如何使用Beautiful Soup ...
- es elasticsearch-head安装
---恢复内容开始--- 参考 https://www.jianshu.com/p/36d7f97a20cd 1.下载安装git clone git://github.com/mobz/elastic ...