传送门

C - /\/\/\/

题意:

给出一个序列\(\{a_i\}\),先要求其满足以下条件:

  • \(a_i=a_{i+2}\)
  • 共有两个不同的数

你现在可以修改任意个数,现问最少修改个数为多少。

思路:

  • 很明显奇偶分类。
  • 记录奇数位置、偶数位置的最大值和最大出现次数的情况;
  • 因为要求两个数不相同,所以还要维护次大。

注意以下细节就是了。

Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 5;
int n;
int a[N], c[N];
int mx[4], mxv[4];
void add(int x, int p) {
++c[x];
if(c[x] > mx[p]) {
mx[p] = c[x];
mxv[p] = x;
} else if(c[x] > mx[p + 1]) {
mx[p + 1] = c[x];
mxv[p + 1] = x;
}
}
int main() {
ios::sync_with_stdio(false); cin.tie(0);
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= n; i += 2) add(a[i], 0);
for(int i = 1; i < N; i++) c[i] = 0;
for(int i = 2; i <= n; i += 2) add(a[i], 2);
int ans = n;
if(mxv[0] == mxv[2]) {
if(mx[1] > mx[3]) {
ans -= mx[1] + mx[2];
} else if(mx[1] < mx[3]){
ans -= mx[0] + mx[3];
} else if(mx[1] == mx[3] && !mx[1]) {
ans -= n / 2;
} else {
ans -= mx[0] + mx[3];
}
} else {
ans -= mx[0] + mx[2];
}
cout << ans;
return 0;
}

D - Robot Arms

题意:

给出平面直角坐标系下的\(n\)个坐标点\((x_i,y_i)\),现要求你确定\(m\)个数\((m\leq 40)\),并且\(n\)种方案。在第\(i\)种方案中,确定一个行走方向的序列\(s\),使得每一步走\(a_i\)的长度能够到达\((x_i,y_i)\)。

思路:

  • 考虑二进制拆分。
  • 因为所有\(a_i\)和的奇偶性不变,即合法情况中,\(x_i+y_i\)的奇偶性也得相同。
  • 但是怎么确定方向?直接来拆显然不行,比如遇到\(0\)的情况。
  • 观察到对于\(a=1\)时,能走的范围是一个斜放的正方形;同理,当\(a=1,2\)时,形状没有变只是边长什么的增加了。
  • 所以对于\(2^0,2^1,\cdots,2^i\),能走的区域有一个限制;如果达到\(2^{i+1}\),这个限制可以被突破,但依然有限制。
  • 但怎么才能有一种方案能走到目标点?
  • 考虑对称操作,即如果让目标点走到原点,从原点出发对称走,也能走到目标点。
  • 所以只要从目标点往回走,每步保证合法(在限制之内)即可。可以证明,最后一定能走回原点。

上面分析的只是\(x_i+y_i\)为奇数的情况,为偶数的话我们先让其往右边走一格,以\((1,0)\)为原点来搞即可。

Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1005; int n, m;
int X[N], Y[N];
ll d[N]; const int dx[5] = {-1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};
const char dc[5] = {'R', 'L', 'U', 'D'}; void getp(ll x, ll y) {
for(int i = m; i; i--) {
int now = d[i];
for(int j = 0; j < 4; j++) {
ll curx = x + d[i] * dx[j], cury = y + d[i] * dy[j];
if(abs(curx) + abs(cury) < now) {
cout << dc[j];
x = curx, y = cury;
break;
}
}
}
} int main() {
ios::sync_with_stdio(false); cin.tie(0);
cin >> n;
int sign = 1, mx = 0;
for(int i = 1; i <= n; i++) cin >> X[i] >> Y[i];
for(int i = 2; i <= n; i++) {
if((abs(X[i] + Y[i]) & 1) != (abs(X[i - 1] + Y[i - 1]) & 1))
sign = 0;
mx = max(mx, abs(X[i]) + abs(Y[i]));
}
if(!sign) {cout << -1; return 0;}
for(d[m = 1] = 1; d[m] << 1 <= mx; ++m, d[m] = d[m - 1] << 1);
if(abs(X[1] + Y[1]) & 1) sign = 0;
cout << m + sign << '\n';
if(sign) cout << 1 << ' ';
for(int i = m; i; i--) cout << d[i] << " \n"[i == 1];
for(int i = 1; i <= n; i++) {
if(sign) cout << 'R';
getp(X[i] - sign, Y[i]);
cout << '\n';
}
return 0;
}

E - Tr/ee

题意:

给出一个\(01\)序列\(s\),现要你构造一棵树满足:若第\(i\)个位置为\(1\),即表示这棵树能够通过去掉一条边得到size为\(i\)的子树;否则为\(0\)则表示不能。

思路:

不合法情况的判断:

  • \(s_1\)一定为\(1\),\(s_n\)一定为\(0\);
  • \(s_i=s_{n-i}\)。

若不满足上面条件则为不合法。

否则,注意到\(s_1\)一定为\(1\),并且\(s_i=s_{n-i}\),那么就可以构造出一颗类似"毛毛虫"的树,存在一条路径作为"body",路径上面的每个结点可能有若干"root"这样的树。

这棵树满足,无论割哪条边,都可以满足条件,具体构造可以看代码。

Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 5; int n;
char s[N]; int main() {
ios::sync_with_stdio(false); cin.tie(0);
cin >> s + 1;
n = strlen(s + 1);
if(s[1] == '0' || s[n] == '1') {cout << -1; return 0;}
for(int i = 1; i < n; i++) if(s[i] != s[n - i]) {
cout << -1; return 0;
}
s[n] = '1';
int rt = 1;
for(int i = 2; i <= n; i++) if(s[i] == '1') {
cout << i << ' ' << rt << '\n';
for(int j = rt + 1; j < i; j++) cout << i << ' ' << j << '\n';
rt = i;
}
return 0;
}

F - Distance Sums

题意:

构造一颗有\(n\)个结点的树,并且给出\(D_i\),这棵树要满足第\(i\)个结点与其它结点距离的累和为\(D_i\)。

如果可以构造,输出方案;否则输出\(-1\)。

思路:

很显然且很重要的一个观察:

  • 叶子结点的\(D\)肯定最大,也就是说,如果从树的底部向上进行拓扑,肯定结点的\(D\)会不断减小。

对于儿子和父亲来说,它们之间满足:\(D_{fa}=D_{son}-sz_{fa}+sz_{son}=D_{son}+2sz_{son}-n\)。

之后按\(D\)值从大到小搞即可,并且合并结点。

那么我们就能判断对于\(i=2,3,\cdots,n\),\(D_i\)是否合法,我们还不能判断\(D_1\)是否合法。

所以最后再暴力\(dfs\)判以下即可。

Code
#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll, int> pli;
const int N = 1e5 + 5; int n;
ll D[N];
pli a[N];
int sz[N]; vector <int> g[N]; void add(int x, int y) {
sz[x] += sz[y];
g[x].push_back(y);
} ll res; void dfs(int u, int fa, ll d) {
res += d;
for(auto v : g[u]) {
if(v != fa) dfs(v, u, d + 1);
}
} int main() {
ios::sync_with_stdio(false); cin.tie(0);
cin >> n;
for(int i = 1; i <= n; i++) cin >> D[i];
for(int i = 1; i <= n; i++) {
a[i] = MP(D[i], i); sz[i] = 1;
}
sort(a + 1, a + n + 1);
int f = 1;
for(int i = n; i > 1 && f; i--) {
ll t = a[i].fi + 2ll * sz[a[i].se] - n;
int x = lower_bound(a + 1, a + i, MP(t, 0)) - a;
if(a[x].fi != t) f = 0;
add(a[x].se, a[i].se);
}
if(f == 0) {cout << -1; return 0;}
dfs(a[1].se, 0, 0);
if(res != a[1].fi) {cout << -1; return 0;}
for(int i = 1; i <= n; i++) {
for(auto it : g[i]) cout << i << ' ' << it << '\n';
}
return 0;
}

AtCoder Regular Contest 103的更多相关文章

  1. AtCoder Regular Contest 103 E Tr/ee

    Tr/ee 思路:按照下图所示连接 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #inclu ...

  2. AtCoder Regular Contest 103 题解

    C-/\/\/\ #include<algorithm> #include<iostream> #include<cstdlib> #include<ioma ...

  3. AtCoder Regular Contest 103 Problem D Robot Arms (构造)

    题目链接  Problem D 给定$n$个坐标,然后让你构造一个长度为$m$的序列, 然后给每个坐标规定一个长度为$m$的序列,ULRD中的一个,意思是走的方向, 每次从原点出发按照这个序列方向,每 ...

  4. AtCoder Regular Contest 061

    AtCoder Regular Contest 061 C.Many Formulas 题意 给长度不超过\(10\)且由\(0\)到\(9\)数字组成的串S. 可以在两数字间放\(+\)号. 求所有 ...

  5. AtCoder Regular Contest 094 (ARC094) CDE题解

    原文链接http://www.cnblogs.com/zhouzhendong/p/8735114.html $AtCoder\ Regular\ Contest\ 094(ARC094)\ CDE$ ...

  6. AtCoder Regular Contest 092

    AtCoder Regular Contest 092 C - 2D Plane 2N Points 题意: 二维平面上给了\(2N\)个点,其中\(N\)个是\(A\)类点,\(N\)个是\(B\) ...

  7. AtCoder Regular Contest 093

    AtCoder Regular Contest 093 C - Traveling Plan 题意: 给定n个点,求出删去i号点时,按顺序从起点到一号点走到n号点最后回到起点所走的路程是多少. \(n ...

  8. AtCoder Regular Contest 094

    AtCoder Regular Contest 094 C - Same Integers 题意: 给定\(a,b,c\)三个数,可以进行两个操作:1.把一个数+2:2.把任意两个数+1.求最少需要几 ...

  9. AtCoder Regular Contest 095

    AtCoder Regular Contest 095 C - Many Medians 题意: 给出n个数,求出去掉第i个数之后所有数的中位数,保证n是偶数. \(n\le 200000\) 分析: ...

随机推荐

  1. Jmeter性能测试分布式技术

    一.什么是分布式测试 分布式测试是指通过局域网和Internet,把分布于不同地点.独立完成特定功能的测试计算机连接起来,以达到测试资源共享.分散操作.集中管理.协同工作.负载均衡.测试过程监控等目的 ...

  2. 极客时间-vue开发实战学习(ant-design vue作者)

    vue基础 属性 事件 插槽 指令(Directives) 生命周期 底层原理 vue生态 路由管理器vue Router 状态管理器vuex 同构Nuxt vue实战 实战项目-ant-desing ...

  3. django找不到模板的错误处理django.template.exceptions.TemplateDoesNotExist: blog/list.html

    错误提示如下图: 程序出错对于程序员而言是最常见的,一般解决的要点是看清错误提示(读懂英文很重要) 根据错误提示 blog\list.html这个文件不存在,也就是没找到资源 这个时候需要去检查有没有 ...

  4. [转]UIpath advanced certification dumps

    本文转自:https://dotnetbasic.com/2019/06/uipath-advanced-certification-dumps.html UiPath advanced certif ...

  5. mysqld_safe error: log-error set to '/data/log/mysqld.log', however file don't exists. Create writable for user 'mysql'.The server quit without updating PID file (/data/mysql/mysqld.pid)

    [oot@cent65 bin]# service mysqld startStarting MySQL.2019-10-28T15:56:47.786960Z mysqld_safe error: ...

  6. Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3

    A,有多个线段,求一条最短的线段长度,能过覆盖到所又线段,例如(2,4)和(5,6) 那么我们需要4 5连起来,长度为1,例如(2,10)(3,11),用(3,10) 思路:我们想一下如果题目说的是最 ...

  7. 蓝牙spp协议分析

    基本概念 蓝牙串口是基于 SPP 协议(Serial Port Profile),能在蓝牙设备之间创建串口进行数据传输的一种设备. 蓝牙串口的目的是针对如何在两个不同设备(通信的两端)上的应用之间保证 ...

  8. 搞定vscode编写java(手把手篇)

    1: 下载VSCODE 本来我写过一个 vscode 编写java 帖子,但是 还是很多人私信我,下面写一个手把手教程 原文地址: https://www.cnblogs.com/dgwblog/p/ ...

  9. python - 操作excel表格

    说明:由于公司oa暂缺,人事妹子在做考勤的时候,需要通过几个excel表格去交叉比对员工是否有旷工或迟到,工作量大而且容易出错. 这时候it屌丝的机会来啦,花了一天时间给妹子撸了一个自动化脚本. 1. ...

  10. Python小练习:StringIO和BytesIO读写操作的小思考

    from io import StringIO; f = StringIO(); f.write('Hello World'); s = f.readline(); print s; 上面这种方法&q ...