牛客周赛 Round 56
写在前面
这场难度不是很高
少见的周赛出了模拟题,还是很好写的,有一点小小的坑
最后一题是个字符串哈希
其他题都是比较偏思维的
代码需要手动展开!!!
A题
直接判断 x + y 与 n 的关系即可
点击查看代码
#include<bits/stdc++.h> #define all(x) (x).begin(), (x).end() #define fi first #define se second #define lowbit(x) (x) & (-x) using i64 = long long; using pii = std::pair<int, int>; void solve() { int x, y, n; std::cin >> x >> y >> n; if (x + y <= n) { std::cout << "YES\n"; } else { std::cout << "NO\n"; } } int main() { std::cin.tie(nullptr); std::cout.tie(nullptr); std::ios::sync_with_stdio(false); int T = 1; //std::cin >> T; while (T --) solve(); return 0; }
B题
注意是m个人和小S一起留下了
所以一共是留下了m + 1个人
一共可以做sum / k个纸飞机
输出min(m + 1, sum / k)即可
注意会溢出int,开long long
点击查看代码
#include<bits/stdc++.h> #define int long long #define all(x) (x).begin(), (x).end() #define fi first #define se second #define lowbit(x) (x) & (-x) using i64 = long long; using pii = std::pair<int, int>; void solve() { int n, m, k; std::cin >> n >> m >> k; std::vector<int> a(n); int sum = 0; for (int i = 0; i < n; i ++) { std::cin >> a[i]; sum += a[i]; } std::cout << std::min(m + 1, sum / k) << '\n'; } signed main() { std::cin.tie(nullptr); std::cout.tie(nullptr); std::ios::sync_with_stdio(false); int T = 1; //std::cin >> T; while (T --) solve(); return 0; }
C题
首先想到的是一个数是1,另一个数是(1 xor a)
但是发现有两个特例
当a == 1时,1 xor a 是 0,不是正整数,但是样例给了,直接输出2和3即可
当a == 1e9时,1 xor a 是 1e9 + 1,大于了1e9,通过对10,100进行打表
可以选择一个数是a - 1,那么另一个数就是(1e9 xor (a - 1))
点击查看代码
#include<bits/stdc++.h> #define int long long #define all(x) (x).begin(), (x).end() #define fi first #define se second #define lowbit(x) (x) & (-x) using i64 = long long; using pii = std::pair<int, int>; void solve() { int a; std::cin >> a; if (a == 1) { std::cout << 2 << ' ' << 3 << '\n'; } else if (a != (int)(1e9)) { std::cout << 1 << " " << (1 ^ a) << '\n'; } else { int x = (int)(1e9) - 1; int s = 1e9; std::cout << x << " " << (x ^ s) << '\n'; } } signed main() { std::cin.tie(nullptr); std::cout.tie(nullptr); std::ios::sync_with_stdio(false); int T = 1; std::cin >> T; while (T --) solve(); return 0; }
D题
三角形的三边a, b, c(a <= b <= c)满足 a + b > c
那么可以对边进行排序,每次判断相邻的三条边
证明
如果a[i], a[i + 1], a[i + 2]不满足
a[i - 1], a[i + 1], a[i + 2]一定不满足
如果a[i - 1], a[i + 1], a[i + 2]满足
a[i], a[i + 1], a[i + 2]一定满足
点击查看代码
#include<bits/stdc++.h> #define int long long #define all(x) (x).begin(), (x).end() #define fi first #define se second #define lowbit(x) (x) & (-x) using i64 = long long; using pii = std::pair<int, int>; void solve() { int n; std::cin >> n; std::vector<int> a(n); for (int i = 0; i < n; i ++) { std::cin >> a[i]; } std::sort(all(a)); int max = -1; for (int i = 0; i + 2 < n; i ++) { if (a[i] + a[i + 1] > a[i + 2]) { max = std::max(max, a[i] + a[i + 1] + a[i + 2]); } } std::cout << max << '\n'; } signed main() { std::cin.tie(nullptr); std::cout.tie(nullptr); std::ios::sync_with_stdio(false); int T = 1; std::cin >> T; while (T --) solve(); return 0; }
E题
模拟题,按题意写就可以
判断是否是开心的时间段,可以用差分数组来维护,然后O(1)判断
时间的输入可以用scanf("%d:%d", &h, &m)
时间前后的判断,可以转换成分钟进行判断
奶茶是否是喜欢的,用set维护就行
注意一个点,输入的开心时间段可能存在开始时间的分钟数大于结束的分钟数
如下图
对这种时间段进行差分的时候,注意一下即可
点击查看代码
#include<bits/stdc++.h> #define all(x) (x).begin(), (x).end() #define fi first #define se second #define lowbit(x) (x) & (-x) using i64 = long long; using pii = std::pair<int, int>; void solve() { int n, m; std::cin >> n >> m; std::vector<int> b(24 * 60 + 2); for (int i = 0; i < n; i ++) { int h1, m1, h2, m2; scanf("%d:%d %d:%d", &h1, &m1, &h2, &m2); int s = h1 * 60 + m1; int t = h2 * 60 + m2; if (s == t) { b[0] ++; } b[s] ++; b[t + 1] --; } for (int i = 1; i <= 24 * 60; i ++) { b[i] += b[i - 1]; } std::set<std::string> st; for (int i = 0; i < m; i ++) { std::string s; std::cin >> s; st.insert(s); } int q; std::cin >> q; while (q --) { int h, m; scanf("%d:%d", &h, &m); int t = h * 60 + m; int h1, m1, h2, m2; scanf("%d:%d %d:%d", &h1, &m1, &h2, &m2); int t1 = h1 * 60 + m1; int t2 = h2 * 60 + m2; std::string s; std::cin >> s; if (!(t >= 0 && t <= 60 + 59)) { std::cout << "Loser xqq\n"; continue; } if (b[t] == 0) { std::cout << "Loser xqq\n"; continue; } if (t1 > t2) { std::cout << "Joker xqq\n"; continue; } if (!st.count(s)) { std::cout << "Joker xqq\n"; continue; } std::cout << "Winner xqq\n"; } } int main() { // std::cin.tie(nullptr); // std::cout.tie(nullptr); // std::ios::sync_with_stdio(false); int T = 1; //std::cin >> T; while (T --) solve(); return 0; }
F题
二分+字符串哈希
本题会卡自然溢出hash
组题人原话
对s,t,以及翻转后的s进行哈希
哈希数组分别是hs[], ht[], rhs[]
然后遍历翻转点,然后二分lcp长度
判断lcp是否相等
翻转点是id,二分的lcp长度是x
t的好说,直接可以求出来
gethash(ht, 1, x)
s的判断情况
二分的长度在翻转区间内,即 x <= id
gethash(rhs, n - id + 1, n - id + x)
否则是
gethash(rhs, n - id + 1, n) * p[x - id] + gethash(hs, id + 1, x)
点击查看代码
#include<bits/stdc++.h> #define all(x) (x).begin(), (x).end() #define fi first #define se second #define lowbit(x) (x) & (-x) using i64 = long long; using u64 = unsigned long long; using pii = std::pair<int, int>; const int P = 13331; const i64 mod = 1610612741; void solve() { int n; std::cin >> n; std::string s, t; std::cin >> s >> t; std::vector<i64> p(n + 1), hs(n + 1), rhs(n + 1), ht(n + 1); p[0] = 1; for (int i = 0; i < n; i ++) { p[i + 1] = p[i] * P % mod; hs[i + 1] = (hs[i] * P + s[i]) % mod; ht[i + 1] = (ht[i] * P + t[i]) % mod; } std::reverse(all(s)); for (int i = 0; i < n; i ++) { rhs[i + 1] = (rhs[i] * P + s[i]) % mod; } int max = -1; int pos = 0; auto gethash = [&](std::vector<i64>& h, int l, int r) -> i64 { return ((h[r] - h[l - 1] * p[r - l + 1]) % mod + mod) % mod; }; auto check = [&](int id, int x) -> bool { u64 S; if (x <= id) { S = gethash(rhs, n - id + 1, n - id + x); } else { S = (gethash(rhs, n - id + 1, n) * p[x - id] % mod + gethash(hs, id + 1, x)) % mod; } u64 T = ht[x]; // std::cerr << S << " " << T << '\n'; return S == T; }; for (int i = 1; i <= n; i ++) { int l = 0, r = n; while (l < r) { int mid = l + r + 1 >> 1; // std::cerr << l << " " << r << " " << mid << '\n'; if (check(i, mid)) { l = mid; } else { r = mid - 1; } } // std::cerr << l << "\n\n"; if (max < l) { max = l; pos = i; } } std::cout << max << ' ' << pos << '\n'; // std::cerr << '\n'; } int main() { std::cin.tie(nullptr); std::cout.tie(nullptr); std::ios::sync_with_stdio(false); int T = 1; std::cin >> T; while (T --) solve(); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通