首页 > 其他分享 >「题解」Codeforces Round 891 (Div. 3)

「题解」Codeforces Round 891 (Div. 3)

时间:2023-10-05 19:23:52浏览次数:46  
标签:891 return int 题解 scanf long max Div ll

A. Array Coloring

Problem

题目

Sol & Code

只有数列的和为偶数时才符合要求,即有任意个偶数,偶数个奇数。

将这些数分成两部分,发现两部分初始值 \(0\) 为偶数,偶数不会影响奇偶性,故需要偶数个奇数。

#include <bits/stdc++.h>
#define N 51

typedef long long ll;

int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }

int T, n, a[N];

int main() {
  scanf("%d", &T);
  while (T--) {
    scanf("%d", &n);
    int sum = 0;
    for (int i = 1 ; i <= n; ++i) {
      scanf("%d", &a[i]);
      sum += a[i];
    }
    if (sum & 1) puts("NO");
    else puts("YES");
  }
  return 0;
}

B. Maximum Rounding

Problem

题目

Sol & Code

贪心,尽量进位即可

#include <bits/stdc++.h>

typedef long long ll;

int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }

int T;
std::string s;

int main() {
  scanf("%d", &T);
  while (T--) {
    std::cin >> s;
    int n = s.length();
    int res = 0, pos = n;
    for (int i = n - 1; i >= 0; --i) {
      if (s[i] + res - '0' >= 5) res = 1, pos = i;
      else res = 0;
    }
    if (pos == n) std::cout << s << '\n';
    else {
      for (int i = 0; i < pos - 1; ++i) putchar(s[i]);
      if (pos == 0) putchar('1');
      else putchar(s[pos - 1] + 1);
      for (int i = pos; i < n; ++i) putchar('0');
      puts("");
    }
  }
  return 0;
}

C. Assembly via Minimums

Problem

题目

Sol & Code

最小的数出现 \(n-1\) 次,次小的数出现 \(n-2\) 次,依次递推,最大的数取最大值即可,可知答案。

#include <bits/stdc++.h>
#define N 1000001

typedef long long ll;

int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }

int T, n, a[N];

int main() {
  scanf("%d", &T);
  while (T--) {
    scanf("%d", &n);
    int s = n * (n - 1) / 2;
    for (int i = 1; i <= s; ++i) scanf("%d", &a[i]);
    std::sort(a + 1, a + s + 1);
    int now = 1, ad = n - 1;
    while (now <= s) {
      printf("%d ", a[now]);
      now += ad;
      --ad;
    }
    printf("%d\n", a[s]);
  }
  return 0;
}

D. Strong Vertices

Problem

题目

Sol & Code

讨论两种情况 \(u\) 到 \(v\) 有直接相连的路径有 \(a_u-a_v \geq b_u-b_v\),移相后 \(a_u - b_u \geq a_v - b_v\)。

如果 \(u\) 到 \(w\),\(w\) 到 \(v\) 则有 \(a_u-a_v \geq b_w-b_w,a_w-a_w \geq b_v-b_v\) 相加得 \(a_u-a_v \geq b_u-b_v\),即只要 \(u\) 能到 \(v\) 则有 \(a_u - b_u \geq a_v - b_v\)。

所以答案就是 \(a_u-a_v\) 的值为最大值的那几个。

我 nt 地用了 st。

#include <bits/stdc++.h>
#define N 200001

typedef long long ll;

int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }

int T, n, a[N], b[N], lg[N], ans[N], f[N][21];

int st(int l, int r) {
  if (l > r) return -2147483647;
  int len = r - l + 1;
  return max(f[l][lg[len] - 1], f[r - (1 << (lg[len] - 1)) + 1][lg[len] - 1]);
}

int main() {
  scanf("%d", &T);
  for (int i = 1; i < N; ++i) {
    lg[i] = lg[i - 1] + ((1 << lg[i - 1]) == i);
  }
  while (T--) {
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
    for (int i = 1; i <= n; ++i) scanf("%d", &b[i]);
    for (int i = 1; i <= n; ++i) f[i][0] = a[i] - b[i];
    for (int j = 1; (1 << j) <= n; ++j) {
      for (int i = 1; i + (1 << j) - 1 <= n; ++i) {
        f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
      }
    }
    int cnt = 0;
    for (int i = 1; i <= n; ++i) {
      if (f[i][0] >= max(st(1, i - 1), st(i + 1, n))) ans[++cnt] = i;
    }
    printf("%d\n", cnt);
    for (int i = 1; i <= cnt; ++i) printf("%d ", ans[i]);
    puts("");
  }
  return 0;
}

E. Power of Points

Problem

题目

Sol & Code

可以发现答案是从这点到所有点的连线的长度和,每次统计答案 \(O(n)\),更新同理。

发现排序后更新只与前后点的数量有关,只需要 \(O(1)\) 更新。

#include <bits/stdc++.h>
#define N 200001

typedef long long ll;

int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }

int T, n;
ll ans[N];
struct point {
  int x, id;
  friend bool operator < (point p1, point p2) {
    return p1.x < p2.x;
  }
}p[N];

int main() {
  scanf("%d", &T);
  while (T--) {
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
      scanf("%d", &p[i].x);
      p[i].id = i;
    }
    std::sort(p + 1, p + n + 1);
    ans[p[1].id] = 0;
    for (int i = 1; i <= n; ++i) ans[p[1].id] += std::abs(p[1].x - p[i].x) + 1;
    for (int i = 2; i <= n; ++i) {
      if (p[i].x != p[i - 1].x) {
        ans[p[i].id] = ans[p[i - 1].id] + 1ll * (p[i].x - p[i - 1].x) * (i - 1) - 1ll * (p[i].x - p[i - 1].x) * (n - i + 1);
      } else ans[p[i].id] = ans[p[i - 1].id];
    }
    for (int i = 1; i <= n; ++i) printf("%lld ", ans[i]);
    puts("");
  }
  return 0;
}

标签:891,return,int,题解,scanf,long,max,Div,ll
From: https://www.cnblogs.com/poi-bolg-poi/p/17743772.html

相关文章

  • P9712 「QFOI R1」贴贴 の 题解
    这道题比较典型。大概就是你先输出solution-,之后再处理其他的。之后遍历字符串,如果发现是大写,就给转成小写,之后输出,如果发现是减号,就输出字符串,都不是就直接输出该字符串的第\(i\)个字符。#include<iostream>#include<string>usingnamespacestd;strings;intlen;int......
  • 实现文档AI搜索,提高问题解决效率
    在当今的数字时代,以AI为动力的文档搜索变得越来越重要。随着在线提供信息的指数增长,传统的搜索方法通常效率低下且耗时。实施文档AI搜索可以显著提高搜索相关文档的效率和有效性。|在网站中实施文档AI搜索的好处很多首先,它通过提供无缝且直观的搜索过程来增强用户体验。借助文档AI......
  • 【基环树 | 题解】P5022 [NOIP2018 提高组] 旅行
    前言一日知基环树弱,固补题。关于基环树基环树定义一个环,环上每个点都有一颗以该点为根的树,如下图为一棵基环树关于基环树常规思路通常来说基环树常规思路是先处理环上树的结果,后通过树的结果来处理换上结果。具体处理方式依照题目来定。然而只是通常来说因为基环树的问......
  • CF1249(Div. 3) 题解(A to D)
    \(\texttt{EF}\)忘(不)记(会)写了。AYetAnotherDividingintoTeams题解题目大意有一个长度为\(n\)的序列\(a_1,a_2,\cdots,a_n\),将他们分为若干组,使得每一组没有两个数的差为\(1\),使分的组数尽可能少。解题思路排完序后对于任意\(1\lei<n\)均有\(a_i\)与\(a_{i......
  • Luogu CF1174C 题解
    这道题其实不难。\(\gcd(i,j)=1\),其实就是\(i\)与\(j\)互质。如果\(i\)与\(j\)不互质,那么我们一定要让\(a_i\)与\(a_j\)相同,只有这样,才能使\(a\)序列中的最大值最小化。所以,我们可以使用埃氏筛法,当筛到质数时,给它和它的倍数都赋值为一个新数。ACCode:#include......
  • Luogu P8651 题解
    这是让我最崩溃的一道橙题了。整整11次提交才AC。这道题有几个要点必须注意:判断日期是否合理。按顺序输出。判断重复的日期。首先,我们来看怎么判断日期是否合理。我们知道大月有\(31\)天,小月有\(30\)天,二月看平年闰年。所以,我们可以写出这样的代码:boolc......
  • Luogu CF1469B 题解
    这道题其实并不难。题目大意是这样的:已知两个序列\(r\)和\(b\),求出合并后的最大前缀和。很好发现:答案就是\(r\)和\(b\)各自的最大前缀和之和。但要注意:\(r\)和\(b\)可以什么都不取,因此\(maxa\)和\(maxb\)初始要赋值为\(0\)。ACCode:#include<iostream>using......
  • Luogu CF755B 题解
    这题其实不难。两人最佳的方案就是先说对方会的词。不难证明,设先手会说\(n\)个单词,后手会说\(m\)个单词,若\(n>m\),则先手胜,若\(n<m\),则后手胜。那如果\(n=m\)呢?假设两人都会说的单词数为\(k\),那么一番推理发现,当两人说了\(k-1\)次,就没有两人都会的词了,可以回到之......
  • Luogu CF1133B 题解
    这道题其实很简单要让两数和为\(k\)的倍数,需要满足以下两条件之一:两数都是\(k\)的倍数两数的余数和为\(k\)因此,我们可以先统计出余数再按上述条件算出共有多少组,即可得到答案注意:当\(k\)为偶数时,余数为\(k/2\)的数要两两配对,不要多算这里统计的是组数,......
  • Luogu P7627 题解
    这题其实不难但如果用暴力,肯定过不了所以我们得想另一种办法我们发现,只有\(1\)异或\(0\)的值为\(1\)例如:\(1\),\(0\),\(1\)两两异或的和为2其实就是每个\(0\)与每一个\(1\)异或时,\(sum\)要加\(1\)所以,我们只要把每一位的\(0\)和\(1\)的数量都统计出来......