牛客周赛 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;
}
posted @   KXDdesu  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示