牛客周赛 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 @ 2024-08-19 02:59  KXDdesu  阅读(15)  评论(0编辑  收藏  举报