Codeforces Round #612
Posted kzns
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #612相关的知识,希望对你有一定的参考价值。
Garland
题目链接 http://codeforces.com/contest/1286/problem/A
题意
给出一串灯泡,灯泡上编号为 1~n 的一个排列,其中一些灯泡掉落。
定义整串的权值为相邻灯泡编号奇偶不同的对数,求放回灯泡后的最小权值。
题解
编号只有奇偶性有用。统计掉落灯泡编号的奇数个数和偶数个数。缺少灯泡的间隙分为四种,奇数间隙(两端为奇数),偶数间隙(两端为偶数),奇偶间隙(两端数字奇偶性不同),两端的间隙。
对于奇数间隙和偶数间隙,分别填充奇数灯泡和偶数灯泡,剩余灯泡不够无法填充,则权值 +2(因为一定填充了奇偶性不同的一段(个)灯泡);奇偶间隙直接权值 +1;两端的间隙由于在两端,填充奇偶性不同的灯泡也只会让权值加 1。
代码
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
#define Nmax 120
int ls[Nmax];
int N;
int cnt[2];
vector<pair<int, int> > sm[2];
int main()
{
scanf("%d", &N);
cnt[0] = N/2;
cnt[1] = N - cnt[0];
for (int i = 1; i <= N; i++)
{
scanf("%d", &ls[i]);
if (ls[i] == 0)
{
ls[i] = -1;
}
else
{
ls[i] %= 2;
cnt[ls[i]]--;
}
}
if (cnt[0] + cnt[1] == N)
{
if (cnt[0] && cnt[1])
{
printf("1
");
}
else
{
printf("0
");
}
return 0;
}
for (int i = 1; i <= N; i++)
{
if (ls[i] != -1)
{
ls[0] = ls[i];
break;
}
}
for (int i = N; i >= 1; i--)
{
if (ls[i] != -1)
{
ls[N+1] = ls[i];
break;
}
}
int k;
int ans = 0;
int lst = ls[0];
int ct = 0;
for (int i = 1; i <= N+1; i++)
{
if (i == 1 || i == N+1)
{
k = 1;
}
if (ls[i] == -1)
{
ct++;
}
else
{
if (lst == ls[i]) {
sm[lst].push_back(make_pair(k, ct));
k = 0;
ct = 0;
}
else {
ans++;
k = 0;
ct = 0;
lst = ls[i];
}
}
}
sort(sm[0].begin(), sm[0].end());
sort(sm[1].begin(), sm[1].end());
for (int j = 0; j < 2; j++) {
for (int i = 0; i < sm[j].size(); i++) {
if (sm[j][i].second <= cnt[j]) {
cnt[j] -= sm[j][i].second;
}
else {
if (sm[j][i].first == 0) {
ans += 2;
}
else {
ans += 1;
}
}
}
}
printf("%d
", ans);
return 0;
}
Numbers on Tree
题目链接 http://codeforces.com/contest/1286/problem/B
题意
给定一棵 n 个结点的树,每个节点有一个未知权值 (a_i)。已知每棵子树中权值小于子树根节点权值的结点个数 (c_i),求一个可行性的权值方案。
题解
显然子树根结点权值是子树中第 (c_i+1) 小的,兄弟子树间权值互不影响。只需要处理完当前结点的子节点后,将当前结点插在第 (c_i+1) 小的位置即可。(n leq 2000),(n^2) 复杂度可以接受,任意插入方式都可。
代码
#include <cstdio>
#include <list>
#include <vector>
using namespace std;
#define Nmax 2020
list<int> ls;
int N;
vector<int> tr[Nmax];
int C[Nmax];
int A[Nmax];
bool flag = false;
void DFS(int x, list<int>::iterator oit) {
list<int>::iterator it;
it = oit;
for (int i = 0; i < tr[x].size(); i++)
{
DFS(tr[x][i], it);
if (flag)
return;
it = ls.end();
it--;
}
oit++;
for (int i = 0; i < C[x]; i++) {
if (oit == ls.end()) {
flag = true;
return;
}
else {
oit++;
}
}
ls.insert(oit, x);
}
int main() {
ls.push_back(0);
list<int>::iterator it;
it = ls.begin();
scanf("%d", &N);
int p, c;
for (int i = 1; i <= N; i++)
{
scanf("%d %d", &p, &C[i]);
tr[p].push_back(i);
}
DFS(tr[0][0], it);
if (flag) {
printf("NO
");
}
else {
printf("YES
");
int i = 1;
for (it++; it != ls.end(); it++) {
A[*it] = i++;
}
for (int i = 1; i <= N; i++) {
printf("%d ", A[i]);
}
}
return 0;
}
以上是关于Codeforces Round #612的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #612 (Div. 2)
Codeforces Round #612 (Div. 2)
Codeforces Round #612 (Div. 2) (A-D)
[Codeforces Round #522 (Div. 2, based on Technocup 2019 Elimination Round 3)][C. Playing Piano](代码片段