传送门

C - /\/\/\/

题意:

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

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

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

思路:

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

注意以下细节就是了。

Code
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int N = 1e5 + 5;
  5. int n;
  6. int a[N], c[N];
  7. int mx[4], mxv[4];
  8. void add(int x, int p) {
  9. ++c[x];
  10. if(c[x] > mx[p]) {
  11. mx[p] = c[x];
  12. mxv[p] = x;
  13. } else if(c[x] > mx[p + 1]) {
  14. mx[p + 1] = c[x];
  15. mxv[p + 1] = x;
  16. }
  17. }
  18. int main() {
  19. ios::sync_with_stdio(false); cin.tie(0);
  20. cin >> n;
  21. for(int i = 1; i <= n; i++) cin >> a[i];
  22. for(int i = 1; i <= n; i += 2) add(a[i], 0);
  23. for(int i = 1; i < N; i++) c[i] = 0;
  24. for(int i = 2; i <= n; i += 2) add(a[i], 2);
  25. int ans = n;
  26. if(mxv[0] == mxv[2]) {
  27. if(mx[1] > mx[3]) {
  28. ans -= mx[1] + mx[2];
  29. } else if(mx[1] < mx[3]){
  30. ans -= mx[0] + mx[3];
  31. } else if(mx[1] == mx[3] && !mx[1]) {
  32. ans -= n / 2;
  33. } else {
  34. ans -= mx[0] + mx[3];
  35. }
  36. } else {
  37. ans -= mx[0] + mx[2];
  38. }
  39. cout << ans;
  40. return 0;
  41. }

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
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int N = 1005;
  5. int n, m;
  6. int X[N], Y[N];
  7. ll d[N];
  8. const int dx[5] = {-1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};
  9. const char dc[5] = {'R', 'L', 'U', 'D'};
  10. void getp(ll x, ll y) {
  11. for(int i = m; i; i--) {
  12. int now = d[i];
  13. for(int j = 0; j < 4; j++) {
  14. ll curx = x + d[i] * dx[j], cury = y + d[i] * dy[j];
  15. if(abs(curx) + abs(cury) < now) {
  16. cout << dc[j];
  17. x = curx, y = cury;
  18. break;
  19. }
  20. }
  21. }
  22. }
  23. int main() {
  24. ios::sync_with_stdio(false); cin.tie(0);
  25. cin >> n;
  26. int sign = 1, mx = 0;
  27. for(int i = 1; i <= n; i++) cin >> X[i] >> Y[i];
  28. for(int i = 2; i <= n; i++) {
  29. if((abs(X[i] + Y[i]) & 1) != (abs(X[i - 1] + Y[i - 1]) & 1))
  30. sign = 0;
  31. mx = max(mx, abs(X[i]) + abs(Y[i]));
  32. }
  33. if(!sign) {cout << -1; return 0;}
  34. for(d[m = 1] = 1; d[m] << 1 <= mx; ++m, d[m] = d[m - 1] << 1);
  35. if(abs(X[1] + Y[1]) & 1) sign = 0;
  36. cout << m + sign << '\n';
  37. if(sign) cout << 1 << ' ';
  38. for(int i = m; i; i--) cout << d[i] << " \n"[i == 1];
  39. for(int i = 1; i <= n; i++) {
  40. if(sign) cout << 'R';
  41. getp(X[i] - sign, Y[i]);
  42. cout << '\n';
  43. }
  44. return 0;
  45. }

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
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int N = 1e5 + 5;
  5. int n;
  6. char s[N];
  7. int main() {
  8. ios::sync_with_stdio(false); cin.tie(0);
  9. cin >> s + 1;
  10. n = strlen(s + 1);
  11. if(s[1] == '0' || s[n] == '1') {cout << -1; return 0;}
  12. for(int i = 1; i < n; i++) if(s[i] != s[n - i]) {
  13. cout << -1; return 0;
  14. }
  15. s[n] = '1';
  16. int rt = 1;
  17. for(int i = 2; i <= n; i++) if(s[i] == '1') {
  18. cout << i << ' ' << rt << '\n';
  19. for(int j = rt + 1; j < i; j++) cout << i << ' ' << j << '\n';
  20. rt = i;
  21. }
  22. return 0;
  23. }

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
  1. #include <bits/stdc++.h>
  2. #define MP make_pair
  3. #define fi first
  4. #define se second
  5. using namespace std;
  6. typedef long long ll;
  7. typedef pair<ll, int> pli;
  8. const int N = 1e5 + 5;
  9. int n;
  10. ll D[N];
  11. pli a[N];
  12. int sz[N];
  13. vector <int> g[N];
  14. void add(int x, int y) {
  15. sz[x] += sz[y];
  16. g[x].push_back(y);
  17. }
  18. ll res;
  19. void dfs(int u, int fa, ll d) {
  20. res += d;
  21. for(auto v : g[u]) {
  22. if(v != fa) dfs(v, u, d + 1);
  23. }
  24. }
  25. int main() {
  26. ios::sync_with_stdio(false); cin.tie(0);
  27. cin >> n;
  28. for(int i = 1; i <= n; i++) cin >> D[i];
  29. for(int i = 1; i <= n; i++) {
  30. a[i] = MP(D[i], i); sz[i] = 1;
  31. }
  32. sort(a + 1, a + n + 1);
  33. int f = 1;
  34. for(int i = n; i > 1 && f; i--) {
  35. ll t = a[i].fi + 2ll * sz[a[i].se] - n;
  36. int x = lower_bound(a + 1, a + i, MP(t, 0)) - a;
  37. if(a[x].fi != t) f = 0;
  38. add(a[x].se, a[i].se);
  39. }
  40. if(f == 0) {cout << -1; return 0;}
  41. dfs(a[1].se, 0, 0);
  42. if(res != a[1].fi) {cout << -1; return 0;}
  43. for(int i = 1; i <= n; i++) {
  44. for(auto it : g[i]) cout << i << ' ' << it << '\n';
  45. }
  46. return 0;
  47. }

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. UWP 在非UI线程中更新UI

    大家都知道,不可以在 其他线程访问 UI 线程,访问 UI 线程包括给 依赖属性设置值.读取依赖属性.调用方法(如果方法里面修改了依赖属性)等.一旦访问UI线程,那么就会报错,为了解决这个问题,需要使 ...

  2. Spring Boot Security 保护你的程序

    Spring Boot Security 本示例要内容 基于角色的权限访问控制 加密.解密 基于Spring Boot Security 权限管理框架保护应用程序 String Security介绍 ...

  3. 更换国内pip

    pip国内的一些镜像 原始地址:https://pypi.python.org/simple 国内地址: 阿里云 http://mirrors.aliyun.com/pypi/simple/ 中国科技 ...

  4. Vue-cli项目部署到Nginx

    项目环境: 0. Nginx使用 以windows版为例,下载niginx压缩包并解压到任意目录,双击nginx.exe,在浏览器中访问http://localhost,如果出现Welcome to ...

  5. 【转载】Java程序模拟公安局人员管理系统

    编程题:公安人员的管理系统1) 学生类:a) 属性:i. 身份号—默认没有,需要手动进行输入ii. 姓名iii. 性别iv. 年龄v. 密码vi. 居住地址vii. 注册日期viii. 人员的信誉程度 ...

  6. 表单生成器(Form Builder)之伪造表单数据番外篇——随机车辆牌照

    前几天记录了一下表单生成器(Form Builder)之表单数据存储结构mongodb篇,之后便想着伪造一些数据.为什么要伪造数据呢?说来惭愧,因为拖拉拽设计表单以及表单对应的列表的PC端和移动端该显 ...

  7. Java基础 - volatile

    volatile的作用:对与volatile修饰的变量, 1,保证该变量对所有线程的可见性. 2,禁止指令重排序. Java内存模型(JMM) 原子性 i = 2; 把i加载到工作内存副本i,副本i= ...

  8. 剑指Offer-38.平衡二叉树(C++/Java)

    题目: 输入一棵二叉树,判断该二叉树是否是平衡二叉树. 分析: 可以从根节点开始遍历每一个节点,求得节点左右子树的最大高度,判断是不是平衡二叉树.这样做的问题在于会重复遍历节点,造成不必要的浪费. 所 ...

  9. javascript es6 Promise 异步同步的写法(史上最简单的教程了)

    1 来个简单的例子 var p = new Promise(function(resolve, reject){ //做一些异步操作 setTimeout(function(){ console.lo ...

  10. (转)简单移动平均线(Simple Moving Average,SMA) 定义及使用

    原文链接:https://blog.csdn.net/Enjolras_fuu/article/details/88602309   扩展:https://www.investopedia.com/t ...