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)的矩阵,每个格子代表海或者陆地,给出在陆地上的起点终 ...
随机推荐
- 用Navicat连接阿里云ECS服务器上的MySQL数据库
今天用navtive连接阿里云服务器(Linux)的数据库时,老是连接不上,并且报10060错误,要通过以下两个步骤解决: 1.先进入linux连接数据库并输入密码: mysql -uroot -p ...
- 网络学习day01_计算机网络与分层思想
2018.9.1 网络学习day01_计算机网络与分层思想 网络安全 计算机网络 分层思想 LAN与WAN LAN(Local Area Network)--局域网 局域网(Local ...
- JSP标签和JSTL
Java的5个标签库:核心(c).格式化(fmt).函数(fn).SQL(sql).XML(x) SQL.XML库不推荐使用 核心标签库(c) //taglib指令 <%@ taglib pre ...
- Lua中的迭代器与泛型for
[前言] 迭代器就是一种可以遍历一种集合中所有元素的机制,在Lua中,通常将迭代器表示为函数.每调用一次函数,就返回集合中的“下一个”元素.每个迭代器都需要在每次成功调用之后保存一些状态,这样才能知道 ...
- 【原创】大叔经验分享(18)hive2.0以后通过beeline执行sql没有进度信息
一 问题 在hive1.2中使用hive或者beeline执行sql都有进度信息,但是升级到hive2.0以后,只有hive执行sql还有进度信息,beeline执行sql完全silence,在等待结 ...
- linux日志过滤某时间段的日志
sed -n '/2019-01-10 16:00*/,/2019-01-10 18:48*/p' nohup.out > 111.log
- JS中 typeof,instanceof类型检测方式
在js中的类型检测目前我所知道的是三种方式,分别有它们的应用场景: 1.typeof:主要用于检测基本类型. typeof undefined;//=> undefined typeof 'a' ...
- 【数据库】MySql分割字符串
上论坛时看到一个骨骼清奇的分割字符串算法. DROP TABLE IF EXISTS Tmp_AreaCode; CREATE TABLE Tmp_AreaCode( string ) )ENGINE ...
- 视频转码成mp4格式,添加关键帧,添加元数据,把元数据放在第一帧,可拖动
作者测试是在windows下使用,所以下载的页面地址是: http://ffmpeg.zeranoe.com/builds/点击页面上的Download FFmpeg git-738ebb4 64-b ...
- tensorflow例子-【老鱼学tensorflow】
本节主要用一个例子来讲述一下基本的tensorflow用法. 在这个例子中,我们首先伪造一些线性数据点,其实这些数据中本身就隐藏了一些规律,但我们假装不知道是什么规律,然后想通过神经网络来揭示这个规律 ...