牛客周赛 Round 73 - A~E

小红的正整数构造

https://ac.nowcoder.com/acm/contest/99277/A

A~E题个人题解

A

找大于l的第一个为x的倍数的数

#include <iostream>
using namespace std;

int main() {
  int l,r,x;
  cin>>l>>r>>x;
  cout<<((l-1)/x*x+x <= r ? (l-1)/x*x+x : -1)<<'\n';
  
  return 0;
}

B

该区间长度最长为(n-1)*x+1 最短为(n+1)*x-1
一种构造方法是先令区间长度最短 然后在左右两侧延长

#include <iostream>
using namespace std;

int main() {
  long long n,k,x;
  cin>>n>>k>>x;
  if (k > (n+1)*x-1 || k < (n-1)*x+1) {
    cout<<-1<<'\n';
    return 0;
  }
  long long l = x, r = x*n;
  k -= (n-1)*x+1;
  l -= min(x-1, k);
  if (l == 1)
    r += k-x+1;
  cout<<l<<' '<<r<<'\n';
  
  return 0;
}

C

最后一位为0时无解 因为全部n个数字一定匹配
一种构造方法是每次查找到1时 从这个下标开始倒序填充

#include <iostream>
#include <vector>
using namespace std;

int main() {
  int n, p = 0;
  string s;
  vector<int> vec;
  cin>>n>>s;
  if (s[n-1] == '0') {
    cout<<-1<<'\n';
    return 0;
  }
  while (s.find('1', p) != string::npos) {
    p = s.find('1', p) + 1;
    int q = p;
    while (vec.size() != p)
      vec.push_back(q--);
  }
  for (auto &x: vec)
    cout<<x<<' ';
  cout<<'\n';
  
  return 0;
}

D

滑动窗口
每多一个1 cnt加上区间内0的个数
每少一个0 cnt减去区间内1的个数

#include <iostream>
using namespace std;

int main() {
  int n;
  long long k;
  string s;
  cin>>n>>k>>s;
  int i = 1, j = 0;
  long long cnt = 0, c0 = 0, c1 = 0;
  while (j < n) {
    while (j < n && cnt < k)
      c0 += s[j] == '0', c1 += s[j] == '1', cnt += s[j] == '1' ? c0 : 0, j++;
    if (cnt == k) {
      cout<<i<<' '<<j<<'\n';
      return 0;
    }
    while (cnt > k)
      c0 -= s[i-1] == '0', c1 -= s[i-1] == '1', cnt -= s[i-1] == '0' ? c1 : 0, i++;
  }
  cout<<-1<<'\n';
  
  return 0;
}

E

只要能把这n个点划分为度数总和相等的两个集合 然后一一匹配 就是满足要求的一个解 因为允许重边
用大小为sum/2的01背包记录某个体积是否可达 同时用bitset记录达成的dp解 找到任意一个解即可

#include <iostream>
#include <bitset>
#include <vector>
using namespace std;

int a[105];
bitset<101> dp[5000];

int main() {
  int n, sum = 0;
  cin>>n;
  for (int i=1; i<=n; i++)
    cin>>a[i], sum += a[i];
  if (sum%2) {
    cout<<-1<<'\n';
    return 0;
  }
  int m = sum/2;
  dp[0][0] = 1;
  for (int i=1; i<=n; i++)
    for (int j=m; j>=a[i]; j--)
      if (dp[j] == 0 && dp[j-a[i]] != 0)
        dp[j] = dp[j-a[i]], dp[j][i] = 1;
  if (dp[m] == 0) {
    cout<<-1<<'\n';
    return 0;
  }
  cout<<m<<'\n';
  vector<int> v1, v2;
  for (int i=1; i<=n; i++)
    dp[m][i] ? v1.push_back(i) : v2.push_back(i);
  int i = 0, j = 0;
  while (m--) {
    cout<<v1[i]<<' '<<v2[j]<<'\n';
    a[v1[i]]--;
    if (a[v1[i]] == 0)
      i++;
    a[v2[j]]--;
    if (a[v2[j]] == 0)
      j++;
  }
  
  return 0;
}
全部评论
C题好像 int q = n; while (vec.size() != n) vec.push_back(q--); 这个地方可以去掉,重复了
点赞 回复 分享
发布于 2025-03-13 11:14 广东
佬D题为什么要看它的第i-1位是1还是0啊,不应该看它第i位吗orz
点赞 回复 分享
发布于 2024-12-23 14:47 黑龙江

相关推荐

首先讲三个故事,关于牛客的事件一:2024年,牛客上有一对高学历情侣,求职方向与我当时一致,都是嵌入式方向。他们恰好是我的朋友,专业能力和学历背景都很扎实,也因此拿到了不少优质offer。和很多求职者一样,他们把offer情况整理后发在平台上,本意是记录与交流,但很快引发了争议。有声音指责他们“集邮”“不释放名额”,认为这种展示本身就是一种炫耀。最终讨论失控,当事人删除内容,事件也很快被遗忘。事件二:小红书评论区,一条评价获得了不少共鸣:“感觉牛客就是当年那群做题区毕业了开始找工作还收不住那股味,颇有一种从年级第一掉到年纪第二后抱怨考不上大学的味道”,这条评论被水印里这个同学转发到牛客后,评论...
小型域名服务器:当看到别人比自己强的时候,即便这是对方应得的,很多人会也下意识的歪曲解构对方的意图,来消解自己在这本就不存在的比较中输掉的自信,从而平白制造出很多无谓的争论。比如你会在空余时间来写优质好文,而我回家只会暗区突围,那么我就可以作为键盘侠在这里评论你是不是XXXXXXXX。即便我自己都知道这是假的,但只要这没那么容易证伪,那么当你开始回应的时候,脏水就已经泼出去了,后面可能会有更多的人带着情绪来给我点赞,而毫不关注你写的文章内容本身是啥了。
SAGIMA牛马咖啡
点赞 评论 收藏
分享
评论
9
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务