寫在前面
這場難度不是很高
少見的周賽出了模擬題,還是很好寫的,有一點小小的坑
最後一題是個字串雜湊
其他題都是比較偏思維的
程式碼需要手動展開!!!
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;
}