Educational Codeforces Round 120 A~C

A. Construct a Rectangle

题意:有三个具有整数长度的棍子l1,l2和l3.把其中一个截成两节,是否能围城一个矩形。
思路:如果最长的等于两根短的之和,可以组成,不行的如果有两根相同并且第三根是偶数,也是可以。
AC代码:

inline void solve()
{
    
    
  int a, b, c;
  cin >> a >> b >> c;
  if ((a == b && c % 2 == 0) || (a == c && b % 2 == 0) || (b == c && a % 2 == 0))
    cout << "YES" << endl;
  else if ((a == (b + c)) || (b == (a + c)) || (c == (a + b)))
    cout << "YES" << endl;
  else
    cout << "NO" << endl;
}

B. Berland Music

题意:输入一个数n,给出n首歌曲评分的排列。给出一个长度为n且只为1或0的字符串s,每一个0或1对应一首歌曲的评价。要求根据s对歌曲重新评分并重新输出排列。重新评分的要求为:1.重新评分后得到的也需要是一个排列。2.评价为1的歌曲评分一定要比评价为0的歌曲高。3.使得新排列的次序尽可能接近原排列。

思路:用map标记一下就可以了。

inline void solve()
{
    
    
  int n;
  cin >> n;
  vector<int> v(n);
  for (int i = 0; i < n; i++)
  {
    
    
    cin >> v[i];
  }
  string s;
  cin >> s;
  map<int, int> mp, mp1;
  rep(i, 0, n - 1)
  {
    
    
    if (s[i] == '0')
    {
    
    
      mp[v[i]] = 0;
    }
    else
    {
    
    
      mp1[v[i]] = 1;
    }
  }
  int c = 1;
  for (auto &i : mp)
  {
    
    
    i.second = c;
    c++;
  }
  for (auto &i : mp1)
  {
    
    
    i.second = c;
    c++;
  }
  rep(i, 0, n - 1)
  {
    
    
    if (mp.find(v[i]) != mp.end())
    {
    
    
      cout << mp[v[i]];
    }
    else
    {
    
    
      cout << mp1[v[i]];
    }
    cout << " ";
  }
  cout << endl;
}

C. Set or Decrease

题意:
给你一个数组 A A A和整数 K K K
两种操作:

  • 选择某个索引 i i i并将 A i A_i Ai减少 1 1 1(使 A i = A i − 1 A_i=A_{i-1} Ai=Ai1)。
  • 或者选择两个索引 i i i j j j,将 A i A_i Ai等于 A j A_j Aj(使 A i = A j A_i=A_j Ai=Aj)。
    使数组总和小于 K K K,你需要的最小步骤数是什么?(你可以使数组的值为负数)。
    思路:
    一定是先对最小的元素使用 -1 操作,再从大到小把元素变为最小值`` 这样一定是最少操作将序列和减到 k 一下 操作数 = 操作 1 的个数 + 操作 2 的个数,操作 1 可能有很多次,操作 2 是将较大的元素变为最小值,所以可能是 [0, n - 1] 次,所以可以枚举操作 2 的个数
    二分+贪心
bool check(int mid)
{
    
    
  int minn = 1e18;
  for (int i = max(0ll, mid - n + 1); i <= mid; i++)
  {
    
    
    int j = mid - i;
    minn = min(minn, sum[n] - ((sum[n] - sum[n - j]) - j * (a[1] - i)) - i);
  }
  return minn <= k;
}
inline void solve()
{
    
    
  cin >> n >> k;
  for (int i = 0; i <= n + 3; i++)
  {
    
    
    sum[i] = 0;
  }
  for (int i = 1; i <= n; i++)
  {
    
    
    cin >> a[i];
  }
  sort(a + 1, a + n + 1);
  for (int i = 1; i <= n; i++)
  {
    
    
    sum[i] = sum[i - 1] + a[i];
  }
  if (sum[n] <= k)
  {
    
    
    cout << 0 << endl;
    return;
  }
  int l = 0, r = sum[n] - k, ans;
  while (l <= r)
  {
    
    
    int mid = (l + r) / 2;
    if (check(mid))
    {
    
    
      r = mid - 1;
      ans = mid;
    }
    else
      l = mid + 1;
  }
  cout << ans << endl;
}

猜你喜欢

转载自blog.csdn.net/qq_45148277/article/details/126340829
今日推荐