2023牛客算法基础训练营补题5

A

solve

二分+前缀和,签到

//                  ξ†(ᗜ ˰ ᗜ)†ξ
//           去吧,鸭鸭,把希儿和AC都带回来!
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N = 1e5 + 5;
int s[N];
int pre[N];
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
inline void print(int x) {
  if (x < 0) {
    putchar('-');
    x = -x;
  }
  if (x > 9)
    print(x / 10);
  putchar(x % 10 + '0');
}
signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, q;
  cin >> n >> q;
  for (int i = 1; i <= n; i++) {
    cin >> s[i];
  }
  sort(s + 1, s + 1 + n);

  for (int i = 1; i <= n; i++)
    pre[i] = pre[i - 1] + s[i];

  while (q--) {
    int k, x;
    cin >> k >> x;
    int l = 1, r = n;
    while (l < r) {
      int mid = l + r >> 1;
      if (s[mid] > x)
        r = mid;
      else
        l = mid + 1;
    }
    if (s[l] > x)
      l--;
    if (k <= l)
      cout << pre[l] - pre[l - k] << endl;
    else
      cout << pre[l] << endl;
  }
  return 0;
}
// 题目所考察知识:
// 心得体会:

B

solve

由于字典序小的获胜,所以每次行动最优都是只拿一个放入该格子
最后只需要比较奇偶即可

//                  ξ†(ᗜ ˰ ᗜ)†ξ
//           去吧,鸭鸭,把希儿和AC都带回来!
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
inline int read(){
  int x=0,f=1;
  char ch=getchar();
  while(ch<'0'||ch>'9'){
    if(ch=='-')
      f=-1;
    ch=getchar();
  }
  while(ch>='0'&&ch<='9'){
    x=x*10+ch-'0';
    ch=getchar();
  }
  return x*f;
  }
inline void print(int x){
  if(x<0){
    putchar('-');
    x=-x;
  }
  if(x>9)
    print(x/10);
    putchar(x%10+'0');
  }
signed main(){
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n;
  cin >> n;
  if(n % 2 == 1) cout << "Yaya-win!" << endl;
  else cout << "win-win!" << endl;
  return 0;
}
//题目所考察知识:
//心得体会:

K

solve

显然每次行动的最优指令是 n/2 + 1,这样可以保证淘汰最多的人

//                  ξ†(ᗜ ˰ ᗜ)†ξ
//           去吧,鸭鸭,把希儿和AC都带回来!
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
inline void print(int x) {
  if (x < 0) {
    putchar('-');
    x = -x;
  }
  if (x > 9)
    print(x / 10);
  putchar(x % 10 + '0');
}
signed main() {
  // ios::sync_with_stdio(false);
  // cin.tie(0);
  int n;
  n = read();
  int res = 0;
  while (n > 2) {
    n = n / 2 + 1;
    res += 1;
  }
  printf("%d\n", res);
  return 0;
}
// 题目所考察知识:
// 心得体会:

H

solve

模拟即可

//                  ξ†(ᗜ ˰ ᗜ)†ξ
//           去吧,鸭鸭,把希儿和AC都带回来!
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
inline void print(int x) {
  if (x < 0) {
    putchar('-');
    x = -x;
  }
  if (x > 9)
    print(x / 10);
  putchar(x % 10 + '0');
}
signed main() {
  // ios::sync_with_stdio(false);
  // cin.tie(0);
  int x, y, k, n, t;
  x = read(), y = read(), k = read(), n = read(), t = read();
  int res = 0;
  int now = x;
  int num = 0;
  for (int i = n; i >= 1; i--) {
    res += i * now;
    num += i;
    if (res >= t) {
      printf("%lld\n", n - i + 1);
      return 0;
    }
    int p = num / k;
    now = x + p * y;
    // cout << now << endl;
  }
  // cout << res << endl;
  if (res >= t)
    printf("%lld\n", n);
  else
    printf("-1\n");
  return 0;
}
// 题目所考察知识:
// 心得体会:

L

solve

完全背包
dp[x]表示剩下x个人时所耗费的最小代价
与完全背包有些许差别,注意循环的顺序
与上一题不同,最后可能到不了0,1,2的最优解
需要从后往前寻找答案

//                  ξ†(ᗜ ˰ ᗜ)†ξ
//           去吧,鸭鸭,把希儿和AC都带回来!
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N = 1e5 + 5;
const int INF = 0x3f3f3f3f3f3f3f3f;
int b[N], x[N];
int dp[N];
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
inline void print(int x) {
  if (x < 0) {
    putchar('-');
    x = -x;
  }
  if (x > 9)
    print(x / 10);
  putchar(x % 10 + '0');
}
signed main() {
  // ios::sync_with_stdio(false);
  // cin.tie(0);
  int n, m;
  n = read(), m = read();
  for (int i = 1; i <= m; i++)
    b[i] = read(), x[i] = read();

  for (int i = 0; i <= n; i++)
    dp[i] = INF;
  dp[n] = 0;
  for (int j = n; j >= 0; j--) {
    for (int i = 1; i <= m; i++) {
      if (j <= x[i])
        continue;
      int z = j % x[i];
      dp[j - z] = min(dp[j - z], dp[j] + b[i]);
    }
  }
  int res = INF;
  for (int i = n; i >= 0; i--) {
    if (res > dp[i])
      res = dp[i];
    else if (dp[i] != INF)
      res = dp[i];
  }
  printf("%lld\n", res);
  return 0;
}
// 题目所考察知识:
// 心得体会:

D

solve

用优先队列维护,每次询问进行区间合并即可

//                  ξ†(ᗜ ˰ ᗜ)†ξ
//           去吧,鸭鸭,把希儿和AC都带回来!
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N = 1e5 + 5;
int r1[N];
int l1[N];
int r2[N];
int l2[N];
struct node {
  int l, r;
  bool operator<(const node p) const { return l > p.l; }
};
priority_queue<node> que1;
priority_queue<node> que2;
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
inline void print(int x) {
  if (x < 0) {
    putchar('-');
    x = -x;
  }
  if (x > 9)
    print(x / 10);
  putchar(x % 10 + '0');
}
signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n;
  n = read();
  int rx = 0, ry = 0;
  for (int i = 1; i <= n; i++)
    l1[i] = read(), r1[i] = read();
  for (int i = 1; i <= n; i++)
    l2[i] = read(), r2[i] = read();

  for (int i = 1; i <= n; i++) {
    node p{l1[i], r1[i]};
    node q{l2[i], r2[i]};
    que1.push(p);
    que2.push(q);

    while (!que1.empty()) {
      node p1 = que1.top();
      if (p1.l <= rx + 1) {
        rx = max(rx, p1.r);
        que1.pop();

      } else
        break;
    }

    while (!que2.empty()) {
      node p2 = que2.top();
      if (p2.l <= ry + 1) {
        ry = max(ry, p2.r);
        que2.pop();

      } else
        break;
    }

    // cout << rx << " " << ry << endl;
    if (rx > ry) {
      printf("sa_win!\n");
      printf("%lld\n", rx - ry);
    } else if (rx < ry) {
      printf("ya_win!\n");
      printf("%lld\n", ry - rx);
    } else {
      printf("win_win!\n");
      printf("0\n");
    }
  }
  return 0;
}
// 题目所考察知识:
// 心得体会:

C

solve

思维题,考虑细节比较多

//                  ξ†(ᗜ ˰ ᗜ)†ξ
//           去吧,鸭鸭,把希儿和AC都带回来!
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
deque<char> deq1;
deque<char> deq2;
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
inline void print(int x) {
  if (x < 0) {
    putchar('-');
    x = -x;
  }
  if (x > 9)
    print(x / 10);
  putchar(x % 10 + '0');
}
signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  string s1, s2;
  cin >> s1 >> s2;
  if (s1.size() == s2.size()) {
    if (s1 == s2)
      cout << "=" << endl;
    else
      cout << "!" << endl;
  } else {
    for (auto s : s1)
      deq1.push_back(s);
    for (auto s : s2)
      deq2.push_back(s);

    while (deq1.size() != 0 && deq2.size() != 0 && deq1.back() == deq2.back()) {
      deq1.pop_back();
      deq2.pop_back();
    }

    int flag = 0;
    int x = deq1.size(), y = deq2.size();
    if (deq1.size() < deq2.size()) {
      char s = deq2[0];
      while (deq2.size() != 0 && deq2.front() == s)
        deq2.pop_front();
      while (deq1.size() != 0 && deq1.front() == s)
        deq1.pop_front();
    } else {
      char s = deq1[0];
      while (deq1.size() != 0 && deq1.front() == s)
        deq1.pop_front();
      while (deq2.size() != 0 && deq2.front() == s)
        deq2.pop_front();
    }
    if (deq1.size() == deq2.size()) {
      cout << "!" << endl;
    } else if (deq1.size() < deq2.size()) {
      if (x > y)
        cout << "!" << endl;
      else
        cout << "<" << endl;
    } else {
      if (x < y)
        cout << "!" << endl;
      else
        cout << ">" << endl;
    }
  }
  return 0;
}
// 题目所考察知识:
// 心得体会:

I

solve

结论题,每次放置的灵石最优是当前剩余灵石/2+1

//                  ξ†(ᗜ ˰ ᗜ)†ξ
//           去吧,鸭鸭,把希儿和AC都带回来!
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N = 1e5 + 5;
int res[N];
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
inline void print(int x) {
  if (x < 0) {
    putchar('-');
    x = -x;
  }
  if (x > 9)
    print(x / 10);
  putchar(x % 10 + '0');
}
signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, m;

  cin >> n >> m;
  for (int i = n; i >= 2; i--) {
    res[i] = m % 2 == 0 ? (m / 2) : (m / 2 + 1);
    m -= res[i];
  }
  res[1] = m;
  if(res[1] <= 0){
    cout << -1 << endl;
    return 0;
  }
  for (int i = 1; i <= n; i++)
    cout << res[i] << " \n"[i == n];
  return 0;
}
// 题目所考察知识:
// 心得体会:

F

solve

模拟+思维
对于字符串前面不合乎要求的字符,应该都放置到后面,用stack维护
如果操作完了后k还有剩余,就把末尾的字符纳入考虑
最后排序即可

//                  ξ†(ᗜ ˰ ᗜ)†ξ
//           去吧,鸭鸭,把希儿和AC都带回来!
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
stack<char> stt;
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
inline void print(int x) {
  if (x < 0) {
    putchar('-');
    x = -x;
  }
  if (x > 9)
    print(x / 10);
  putchar(x % 10 + '0');
}
signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  int n, k;
  cin >> n >> k;
  string s;
  cin >> s;
  string ans;
  for (int i = 0; i < n; i++) {
    while (stt.size() && k) {
      if (stt.top() < s[i]) {
        ans += stt.top();
        stt.pop();
        k--;
      } else
        break;
    }

    stt.push(s[i]);
  }

  while (stt.size() && k) {
    ans += stt.top();
    stt.pop();
    k--;
  }

  sort(ans.begin(), ans.end(), greater<char>());

  string temp;
  while (stt.size()) {
    temp += stt.top();
    stt.pop();
  }
  reverse(temp.begin(), temp.end());

  temp += ans;
  cout << temp << endl;
  return 0;
}
// 题目所考察知识:
// 心得体会:

posted @ 2023-02-02 10:02  Sun-Wind  阅读(22)  评论(0编辑  收藏  举报