abc271_c Manga 题解

Posted lw0的博客园据点

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了abc271_c Manga 题解相关的知识,希望对你有一定的参考价值。

abc271_c Manga 题解

Manga

题意

有一部连载漫画,共 \\(10^9\\) 卷,你手上有 \\(n\\) 卷漫画,第 \\(i\\) 卷是连载中的第 \\(a_i\\) 卷。

你在看漫画之前,可以执行以下操作若干次(可以不执行):

  • 若手上还有至少两卷漫画,可以卖掉任意两卷,并买一卷任意卷数的漫画。

你不想看不连续的漫画,所以你只能从连载第一卷开始读,直到你手上没有连载的下一卷,问你最多可以读多少卷。

数据范围

  • \\(1 \\leqslant n \\leqslant 3 \\times 10^5\\)
  • \\(1 \\leqslant a_i \\leqslant 10^9\\)

思路

首先,我们手上会有重复卷数的漫画,这些废卷可以直接卖掉。

然后就是一个双指针,当手上没有废卷而且还有空缺时,我们可以拿手上卷数最大的漫画(排序)去补空缺,有些细节,总体难度不大。

当然你也可以二分,二分最多能阅读几卷,check函数详见代码。

复杂度

  • 时间:\\(O(n \\log n)\\)
  • 空间:\\(O(n)\\)

Code

排序双指针代码
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 3e5 + 10;

int n, m, a[N], b[N], ans, now = 1, sum;

int main () 
  ios::sync_with_stdio(0), cin.tie(0);
  cin >> m;
  for (int i = 1; i <= m; i++) 
    cin >> b[i];
  
  sort(b + 1, b + m + 1);
  for (int i = 1; i <= m; i++) 
    if (b[i] == b[i - 1])  // 废卷
      sum++; // 统计废卷卷数
     else 
      a[++n] = b[i];
    
  
  for (int i = 1, j = n; i <= j; ) 
    if (a[i] != now)  // 现在考虑的这本不能接上上一卷
      if (sum >= 2)  // 优先使用废卷
        sum -= 2;
       else if (sum)  // 废卷还剩一本,用掉废卷和最后的一卷
        j--, sum = 0;
       else if (j - i >= 1)  // 还有可以卖掉的
        j -= 2; // 卖掉最大的两卷
       else 
        break; // 退出
      
     else 
      i++;
    
    ans++, now++;
  
  cout << ans + sum / 2; // 可能还有废卷,也要卖掉
  return 0;

二分代码
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 3e5 + 10;

int n, m, a[N], b[N], ans, now = 1, sum, l, r;

bool check (int x) 
  int num = sum, cnt = x; // num 统计可以卖掉的卷数,cnt 统计空缺数
  for (int i = 1; i <= n; i++) 
    if (a[i] <= x)  // 在前 x 卷中
      cnt--; // 空缺数减 1
     else 
      num++; // 卖掉它
    
  
  return (cnt * 2 <= num);


int main () 
  ios::sync_with_stdio(0), cin.tie(0);
  cin >> m;
  r = m;
  for (int i = 1; i <= m; i++) 
    cin >> b[i];
  
  sort(b + 1, b + m + 1);
  for (int i = 1; i <= m; i++) 
    if (b[i] == b[i - 1])  // 废卷
      sum++; // 统计废卷卷数
     else 
      a[++n] = b[i];
    
  
  while (l < r) 
    int mid = (l + r + 1) >> 1;
    if (check(mid)) 
      l = mid;
     else 
      r = mid - 1;
    
  
  cout << l;
  return 0;

题解 AT5228 [ABC162A] Lucky 7

AT5228 [ABC162A] Lucky 7

题面中已经保证 (s) 的长度为 (3),也就是说,我们只需要把 (s_0)(s_1)(s_2) 全部判断一遍,只要有一个是 (7),则输出 Yes,否则输出 No

代码:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    string s;
    cin >> s;
    if(s[0] == ‘7‘ || s[1] == ‘7‘ || s[2] == ‘7‘)
        cout << "Yes";
    else 
        cout << "No";
    return 0;
}

以上是关于abc271_c Manga 题解的主要内容,如果未能解决你的问题,请参考以下文章

题解AcWing271杨老师的照相排列

题解 AtCoder abc154 F

Multiplication 3 AtCoder - abc169_c (浮点数精度问题)

abc270_f Transportation 题解

abc269_f Numbered Checker 题解

abc252_d Distinct Trio 题解