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

「题解」Codeforces Round 980 (Div. 2)

时间:2024-10-21 14:59:25浏览次数:1  
标签:std typedef int 题解 980 long Div scanf define

before

\(A \sim D\) 的题解

A. Profitable Interest Rate

Problem

A. Profitable Interest Rate

Sol&Code

数学题,有 \(a - x \geq b - 2x\),得 \(x = b - a\)。

特判 \(a \geq b\) 以及 \(a < x\) 的情况即可。

#include <bits/stdc++.h>

#define M 10001
#define N 100001

typedef long long ll;
typedef std::pair<int, int> pii;

int T, a, b;

int main() {
  scanf("%d", &T);
  while (T--) {
    scanf("%d %d", &a, &b);
    if (a >= b) printf("%d\n", a);
    else {
      int x = b - a;
      printf("%d\n", std::max(0, a - x));
    }
  }
  return 0;
}

B. Buying Lemonade

Problem

B. Buying Lemonade

Sol&Code

一种最优的策略是,首先对已知还有剩余的所有按钮按当前最少的那个次数,然后用一定的次数排除没有库存的按钮,重复执行上述步骤。

#include <bits/stdc++.h>

#define M 10001
#define N 200001

typedef long long ll;
typedef std::pair<int, int> pii;

int T, n, k, a[N];

int main() {
  scanf("%d", &T);
  while (T--) {
    scanf("%d %d", &n, &k);
    for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
    std::sort(a + 1, a + n + 1);
    long long ans = 0, now = 1, minu = 0;
    while (k > 0) {
      while (now < n && a[now] <= minu) ++now, ++ans;
      a[now] -= minu;
      minu += a[now];
      int t = std::min((long long)std::ceil(1.0 * k / a[now]), n - now + 1);
      ans += t * a[now];
      k -= t * a[now];
    }
    printf("%lld\n", ans + k);
  }
  return 0;
}

C. Concatenation of Arrays

Problem

C. Concatenation of Arrays

Sol&Code

考虑对于一定顺序排列的元组,交换当中相邻的两个元组,对于这俩两侧的元组贡献的逆序对数没有影响。

考虑这俩如何排序更优,按元组内的数据和从小到大排。

#include <bits/stdc++.h>

#define M 10001
#define N 100001

typedef long long ll;
typedef std::pair<int, int> pii;

int T, n;
struct Pair {
  int x, y, sum;
  friend bool operator < (Pair p1, Pair p2) {
    if (p1.sum != p2.sum) return p1.sum < p2.sum;
    return std::min(p1.x, p1.y) < std::min(p2.x, p2.y);
  }
}p[N];

int main() {
  scanf("%d", &T);
  while (T--) {
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
      scanf("%d %d", &p[i].x, &p[i].y);
      p[i].sum = p[i].x + p[i].y;
    }
    std::sort(p + 1, p + n + 1);
    for (int i = 1; i <= n; ++i) printf("%d %d ", p[i].x, p[i].y);
    puts("");
  }
  return 0;
}

D. Skipping

Problem

D. Skipping

Sol&Code

发现答案最后一定是对于题目集的一段前缀减去跳过的题目。

于是考虑维护跳到题目 \(i\) 最少跳过多少分,对于 \(1\) 来说是 \(0\)。按照跳到 \(i\) 最少跳过的分数加上 \(i\) 的分数从小到大去更新更大的 \(i\)。用大根堆来做。

#include <bits/stdc++.h>

#define M 10001
#define N 400001
#define inf 100000000000000007

typedef long long ll;
typedef std::pair<ll, ll> pll;

bool used[N];
ll sum[N], skip[N];
int T, n, a[N], b[N];
std::priority_queue<pll> q;

int main() {
  scanf("%d", &T);
  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) sum[i] = sum[i - 1] + a[i];
    for (int i = 1; i <= n; ++i) skip[i] = inf, used[i] = 0;

    skip[1] = 0;
    int nowp = 2;
    q.push({0 - a[1], 1});
    while (!q.empty()) {
      auto [x, y] = q.top();
      q.pop(); x = -x;
      if (b[y] <= y) continue;
      if (used[y]) continue;
      used[y] = true;
      for (int i = std::max((int)y + 1, nowp); i <= b[y]; ++i) {
        skip[i] = std::min(skip[i], (ll)x);
        q.push({0 - a[i] - skip[i], i});
      }
      nowp = std::max(nowp, b[y] + 1);
    }
    long long ans = -inf;
    for (int i = n; i >= 1; --i) ans = std::max(ans, sum[i] - skip[i]);
    printf("%lld\n", ans);
  }
  return 0;
}

After

唉唉,掉大分了。

标签:std,typedef,int,题解,980,long,Div,scanf,define
From: https://www.cnblogs.com/poi-bolg-poi/p/18489506

相关文章

  • 双系统Linux使用windows硬盘导致git报错问题解决
    一.问题产生的背景双系统下ubuntu为了节省空间挂载使用了windows硬盘,在使用最新的gitclone代码后提示“gitfataldetecteddubiousownershipinrepository”,这是git为了安全原因限制登陆用户和仓库文件用户必须一致,否则提示上述错误信息二.问题的解决办法办法1:挂载磁盘时......
  • Educational Codeforces Round 165 (Rated for Div. 2) - VP记录
    A.TwoFriends一共只有两种情况:存在\(A\)的最好朋友是\(B\)且\(B\)的最好朋友是\(A\)的情况:此时只需邀请这两个人即可。不存在上述情况:设某个人\(A\)的最好朋友是\(B\),\(B\)的最好朋友是\(C\),这时邀请\(A,B,C\)三个人就可使\(A,B\)到场。根据上述两种情......
  • Codeforces Round 979 (Div. 2)
    CodeforcesRound979(Div.2)总结A首先第一位的贡献一定是\(0\),然后考虑接下来\(n-1\)位,我们可以把最大值和最小值放在第一位和第二位,这样贡献就是\((max-min)\times(n-1)\)。#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#includ......
  • 「题解」Codeforces Round 979 (Div. 2)
    before\(A\simD\)的题解A.AGiftFromOrangutanProblemA.AGiftFromOrangutanSol&Code\(c_i-b_i\)最大就是\(a\)的最大值减最小值。将\(a\)的最大值\(x\)和最小值\(y\)放到头两位即可得到答案\((x-y)(n-1)\)。#include<bits/stdc++.h>#defineM......
  • Codeforces Round 980 (Div. 2) C. Concatenation of Arrays
    题目:给定n个数组a1,a2,…,an。每个数组的长度都是2。因此,ai=[ai,1,ai,2]。你需要将这些数组连接成一个长度为2n的单一数组,以便使结果数组中的逆序数最小。注意,你不需要实际计算逆序的数量。更正式地说,你需要选择一个长度为n的排列p,使得数组b=[ap1,1,ap1,2,......
  • CF round 979 div2(D-E)
    D容易观察到需要连续一段区间。这不单点修改区间查询,然后我思维就开始往线段树飘了。。。并且我到这里就以为做完了开始想实现,实际上性质都没观察准确。。但是因为这是一个1500的题所以显然有不用线段树的解。题解是差分做的,确实差分也可以操作区间观察到“LR”一定是隔断点,那......
  • AT_abc348_d [ABC348D] Medicines on Grid 题解
    题目传送门题目大意:给定一个\(n\timesm\)的地图,要求从起点S走到终点T,每移动\(1\)个会消耗\(1\)点能量,障碍#不能走,空地为.可以走,体力消耗至\(0\)也无法移动,地图位置\((x_i,y_i)\)有一瓶可以变成\(e_i\)体力的药,可以选择是否喝。问能否抵达终点,可以输出Yes,否......
  • AT_abc374_e [ABC374E] Sensor Optimization Dilemma 2 题解
    洛谷题目传送门AT题目传送门题目大意:给定\(n\)道工序,你有\(X\)元的资金,对于第\(i\)道工序,有两种机器供你选择,第一种机器可以花费\(P_i\)元处理\(A_i\)个产品,第二种机器可以花费\(Q_i\)元处理\(B_i\)个产品。钦定第\(i\)天处理的产品个数为\(W_i\),求在总花费......
  • UVA11294 Wedding 题解
    洛谷题目传送门前排提示:本题需要用到知识点2-SAT以及强联通分量,模板传送门P4782【模板】2-SAT。题目大意:有至多\(30\)对夫妻将会参加一个婚宴。他们将会坐在一个长桌子的两边。新郎新娘坐在彼此相对的一端并且新娘带着一个头饰使得她看不到和她坐在同一边的人。夫妻坐在......
  • SP9685 ZTC - Zombie’s Treasure Chest 题解
    洛谷题目传送门双倍经验简单题。对于空间大小为\(s1\timess2\)时,显然最多可得到的价值为\(\max(s2\timesv1,s1\timesv2)\),剩下小于\(s1\timess2\)的部分选一个占用空间大的枚举就好。时间复杂度:\(O(T\lfloor\frac{m}{\max(s1,s2)}\rfloor)\),其中\(m=n\bmo......