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)的矩阵,每个格子代表海或者陆地,给出在陆地上的起点终 ...
随机推荐
- 网络学习day03_IP地址概述与应用
IP地址 IP地址的定义及分类 主机唯一的标识,保证主机间正常通信 一种网络编码,用来确定网络中一个节点 IP地址是一个32位的二进制数 常见的IP地址,分为IPv4与IPv6两大类. ipv4的形式 ...
- Vue导出json数据到Excel表格
一.安装依赖 npm install file-saver --save npm install xlsx --save npm install script-loader --save-dev 二. ...
- PHP 【五】
函数 如要在页面加载时执行脚本,可以把它放到函数里 函数是通过调用函数来执行的 可在页面的任何位置调用函数 <?phpfunction functionName(){ // 要执行的代码} ...
- 帆软报表(finereport) 折叠树
在进行展现数据时,希望模板的数据是可以动态折叠的,即点击数据前面的加号才展开对应下面的数据,可通过树节点按钮实现折叠树效果 实现思路: 1.这里建立一个内置数据集 添加数据 设置模板样式,添加颜色和对 ...
- 解决jenkins构建job报错“NoClassDefFoundError” in jenkins/scm/RunWithSCM问题
现象 使用Jenkins 2.8,当我运行一个简单的Jenkins工作时,构建一个job获取源代码,出现下面的错误 FATAL: jenkins/scm/RunWithSCM java.lang.No ...
- yum install 报错[Errno 14] curl#37 - Couldn't open file /mnt/repodata/repomd.xml
最近在玩centos7,之前装系统没太注意yum这个东东,今天用别人装好的系统想用yum install 一个东西,结果报各种错,所以就是: 1.然后按照网上的一些修改,先是执行: yum cleam ...
- java----JDOM解析XML
JDOM: 与DOM类似,基于树形结构 效率比DOM快 下载: http://www.jdom.org/dist/binary/jdom-2.0.6.zip 导包导java中的工程目录 jdom-2. ...
- Java基础try-with-resource语法源码分析
众所周知,所有被打开的系统资源,比如流.文件或者Socket连接等,都需要被开发者手动关闭,否则随着程序的不断运行,资源泄露将会累积成重大的生产事故. 在Java的江湖中,存在着一种名为finally ...
- 四.property
将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则 # 例一:BMI指数(bmi是计算而 ...
- Postgresql/Greenplum中将数字转换为字符串TO_CHAR函数前面会多出一个空格
-- 问题1..Postgresql中将数字转换为字符串前面多出一个空格. SELECT TO_CHAR(, '); -- 解决1.使用如下,参数二前面加上fm就可以去掉空格了,如下: SELECT ...