传送门
A - 球?球!
分析
- 这题是个模拟题,需要注意的是不会出现负分,最低是0分,对 s u m − 2 sum - 2 sum−2 和 0 0 0 取 m a x max max 即可
#include<bits/stdc++.h>
using std::cin;
using std::cout;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using pii = std::pair<int, int>;
#define TESTS int _; std::cin >> _; while(_--)
constexpr i64 inf = 1E18, Md3 = 998244353, Md7 = 1e9 + 7;
constexpr double eps = 1E-9;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
TESTS {
int n, z, s;
cin >> n >> z >> s;
i64 sum1 = 0, sum2 = 0;
std::vector<int> a(n), b(n);
for(int i = 0; i < n; i++) {
cin >> a[i];
if(a[i] > s) {
sum1 = std::max(sum1 - 2, 0LL);
} else {
sum1 += 1;
}
}
for(int i = 0; i < n; i++) {
cin >> b[i];
if(b[i] > z) {
sum2 = std::max(sum2 - 2, 0LL);
} else {
sum2 += 1;
}
}
if(sum1 > sum2) {
cout << "zy\n";
} else if(sum1 < sum2) {
cout << "sdy\n";
} else {
cout << "none\n";
}
}
return 0;
}
B - 活动
分析
- 该题只需要判断n与50的大小
#include<bits/stdc++.h>
using std::cin;
using std::cout;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using pii = std::pair<int, int>;
#define TESTS int _; std::cin >> _; while(_--)
constexpr i64 inf = 1E18, Md3 = 998244353, Md7 = 1e9 + 7;
constexpr double eps = 1E-9;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int n;
cin >> n;
if(n >= 50) {
cout << "wy";
} else {
cout << "ty";
}
return 0;
}
C - 分赃
分析
- 这题由于输入很大,即便用 l o n g l o n g long long longlong 也会超,所以输入需要使用字符串
- 非常经典的博弈题,我们可以把前 10 10 10 种情况推出来,会发现其实只需要判断奇偶即可
#include<bits/stdc++.h>
using std::cin;
using std::cout;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using pii = std::pair<int, int>;
#define TESTS int _; std::cin >> _; while(_--)
constexpr i64 inf = 1E18, Md3 = 998244353, Md7 = 1e9 + 7;
constexpr double eps = 1E-9;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::string s;
cin >> s;
if(int(s.back() - '0') % 2 == 0) {
cout << "yxy";
} else {
cout << "clx";
}
return 0;
}
D - 三行四列行列式
分析
- 我们把对应的行和列拿出来,把相交的两个值 a [ x − 1 ] a[x - 1] a[x−1] 和 b [ y − 1 ] b[y - 1] b[y−1] 求和 / 2 = s u m /2 = sum /2=sum,先将行复制到对应的列,列复制到对应的行,最终将交点赋值为 s u m sum sum 即可
#include<bits/stdc++.h>
using std::cin;
using std::cout;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using pii = std::pair<int, int>;
#define TESTS int _; std::cin >> _; while(_--)
constexpr i64 inf = 1E18, Md3 = 998244353, Md7 = 1e9 + 7;
constexpr double eps = 1E-9;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int n;
cin >> n;
std::vector g(n + 1, std::vector<int>(n + 1));
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
cin >> g[i][j];
}
}
int x, y;
cin >> x >> y;
std::vector<int> a = g[x], b;
for(int i = 0; i < a.size() - 1; i++) {
a[i] = a[i + 1];
}
a.pop_back();
for(int i = 1; i <= n; i++) {
b.push_back(g[i][y]);
}
i64 sum = std::ceil((1.0 * a[x - 1] + b[y - 1]) / 2);
for(int i = 0; i < n; i++) {
g[i + 1][y] = a[i];
}
for(int i = 0; i < n; i++) {
g[x][i + 1] = b[i];
}
g[x][y] = sum;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
cout << g[i][j] << " ";
}
cout << "\n";
}
return 0;
}
E - KAKAZL的时间魔咒
分析
- 这题由于是分钟作最小单位,所以将给出的时间转换成分钟,对分钟进行遍历,判断当前分钟是否对称,需要注意的是有可能是第二天才出现对称,所以分情况讨论
- 第一种情况,当前时间到 23 : 59 23:59 23:59
- 第二种情况,第二天的 00 : 00 00:00 00:00 到 当前时间 + 1439 +1439 +1439
#include<bits/stdc++.h>
using std::cin;
using std::cout;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using pii = std::pair<int, int>;
#define TESTS int _; std::cin >> _; while(_--)
constexpr i64 inf = 1E18, Md3 = 998244353, Md7 = 1e9 + 7;
constexpr double eps = 1E-9;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
TESTS {
std::string s;
cin >> s;
int p = s.find(':');
int hh = (s[p - 2] - '0') * 10 + (s[p - 1] - '0');
int mm = (s[p + 1] - '0') * 10 + (s[p + 2] - '0');
int tot = hh * 60 + mm;
int ok = -1;
for(int i = tot; i <= 1439; i++) {
int h = i / 60;
int m = i % 60;
if((h / 10 == m % 10) && (h % 10 == m / 10)) {
ok = i - tot;
break;
}
}
if(ok == -1) {
for(int i = 0; i < tot; i++) {
int h = i / 60;
int m = i % 60;
if((h / 10 == m % 10) && (h % 10 == m / 10)) {
ok = 1440 - tot + i;
break;
}
}
}
int c = (mm + ok) / 60;
mm = (mm + ok) % 60;
hh += c;
if(hh >= 24) {
hh -= 24;
}
printf("%02d:%02d\n", hh, mm);
printf("%d\n", ok);
}
return 0;
}
F - 加训
分析
- 由于原字符串S是一个 没有相邻的重复字母的字符串,所以我们需要把 S ‘ S{`} S‘中相邻的字符给删去,只留下一个,最后判断是否与字符串 T T T 相等即可
#include<bits/stdc++.h>
using std::cin;
using std::cout;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using pii = std::pair<int, int>;
#define TESTS int _; std::cin >> _; while(_--)
constexpr i64 inf = 1E18, Md3 = 998244353, Md7 = 1e9 + 7;
constexpr double eps = 1E-9;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
TESTS {
int n, m;
cin >> n >> m;
std::string s, t;
cin >> s >> t;
int pre = 0;
std::vector<bool> vis(n, true);
for(int i = 1; i < n; i++) {
if(s[i] == s[pre]) {
vis[i] = false;
} else {
pre = i;
}
}
std::string news;
for(int i = 0; i < n; i++) {
if(vis[i]) {
news += s[i];
}
}
if(news == t) {
cout << "YES\n";
} else {
cout << "NO\n";
}
}
return 0;
}
G - 白日登山望烽火,黄昏饮马傍交河
分析
- 找 ( x 1 , y 1 ) (x1, y1) (x1,y1) 的坐标对 x x x 轴作对称和对 y y y 轴作对称,计算出对称点与点 ( x 2 , y 2 ) (x2, y2) (x2,y2) 的距离,然后比较大小即可
#include<bits/stdc++.h>
using std::cin;
using std::cout;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using pii = std::pair<int, int>;
#define TESTS int _; std::cin >> _; while(_--)
constexpr i64 inf = 1E18, Md3 = 998244353, Md7 = 1e9 + 7;
constexpr double eps = 1E-9;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
TESTS {
int x1, y1, x2, y2;
cin >> x1 >> y1 >> x2 >> y2;
i64 s1 = (x1 - x2) * (x1 - x2) + (-y1 - y2) * (-y1 - y2);
i64 s2 = (-x1 - x2) * (-x1 - x2) + (y1 - y2) * (y1 - y2);
if(s1 > s2) {
cout << "y\n";
} else {
cout << "x\n";
}
}
return 0;
}
H - Small Orange的后花园
分析
- 这题需要将原式子展开成 ∑ i = 1 n ∑ j = i n ( a i 2 − 2 a i a j + a j 2 ) = [ n a 1 2 − 2 a 1 ( a 1 + a 2 + ⋯ + a n ) + ( a 1 2 + a 2 2 + … a n 2 ) ] + [ ( n − 1 ) a 2 2 − 2 a 2 ( a 2 + a 3 + ⋯ + a n ) + ( a 2 2 + a 3 2 + … a n 2 ) ] + ⋯ = ( n + 1 ) ∑ i = 1 n ( a i 2 ) − 2 ∑ i = 1 n [ a i ( s u m n − s u m i − 1 ) ] \sum_{i=1}^n \sum_{j = i}^n(a_{i}^2 - 2a_{i}a_{j} + a_{j}^2) = [na_{1}^2 - 2a_{1}(a_{1} + a_{2} + \dots + a_{n}) + (a_{1}^2 + a_{2}^2 + \dots a_{n}^2)] + [(n - 1)a_{2}^2 - 2a_{2}(a_{2} + a_{3} + \dots + a_{n}) + (a_{2}^2 + a_{3}^2 + \dots a_{n}^2)] +\dots =(n + 1)\sum_{i = 1}^n (a_{i}^2)- 2\sum_{i = 1}^n [a_{i}(sum_{n} - sum_{i - 1})] ∑i=1n∑j=in(ai2−2aiaj+aj2)=[na12−2a1(a1+a2+⋯+an)+(a12+a22+…an2)]+[(n−1)a22−2a2(a2+a3+⋯+an)+(a22+a32+…an2)]+⋯=(n+1)∑i=1n(ai2)−2∑i=1n[ai(sumn−sumi−1)],其中 s u m sum sum 为 f i b fib fib 的前缀和
#include<bits/stdc++.h>
using std::cin;
using std::cout;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using pii = std::pair<int, int>;
#define TESTS int _; std::cin >> _; while(_--)
constexpr i64 inf = 1E18, Md3 = 998244353, Md7 = 1e9 + 7, N = 100005;
constexpr double eps = 1E-9;
template<class T>
constexpr T power(T a, i64 b) {
T res = 1;
for (; b; b /= 2, a *= a) {
if (b % 2) {
res *= a;
}
}
return res;
}
constexpr i64 mul(i64 a, i64 b, i64 p) {
i64 res = a * b - i64(1.L * a * b / p) * p;
res %= p;
if (res < 0) {
res += p;
}
return res;
}
template<int P>
struct MInt {
int x;
constexpr MInt() : x{} {}
constexpr MInt(i64 x) : x{norm(x % getMod())} {}
static int Mod;
constexpr static int getMod() {
if (P > 0) {
return P;
} else {
return Mod;
}
}
constexpr static void setMod(int Mod_) {
Mod = Mod_;
}
constexpr int norm(int x) const {
if (x < 0) {
x += getMod();
}
if (x >= getMod()) {
x -= getMod();
}
return x;
}
constexpr int val() const {
return x;
}
explicit constexpr operator int() const {
return x;
}
constexpr MInt operator-() const {
MInt res;
res.x = norm(getMod() - x);
return res;
}
constexpr MInt inv() const {
assert(x != 0);
return power(*this, getMod() - 2);
}
constexpr MInt &operator*=(MInt rhs) & {
x = 1LL * x * rhs.x % getMod();
return *this;
}
constexpr MInt &operator+=(MInt rhs) & {
x = norm(x + rhs.x);
return *this;
}
constexpr MInt &operator-=(MInt rhs) & {
x = norm(x - rhs.x);
return *this;
}
constexpr MInt &operator/=(MInt rhs) & {
return *this *= rhs.inv();
}
friend constexpr MInt operator*(MInt lhs, MInt rhs) {
MInt res = lhs;
res *= rhs;
return res;
}
friend constexpr MInt operator+(MInt lhs, MInt rhs) {
MInt res = lhs;
res += rhs;
return res;
}
friend constexpr MInt operator-(MInt lhs, MInt rhs) {
MInt res = lhs;
res -= rhs;
return res;
}
friend constexpr MInt operator/(MInt lhs, MInt rhs) {
MInt res = lhs;
res /= rhs;
return res;
}
friend constexpr std::istream &operator>>(std::istream &is, MInt &a) {
i64 v;
is >> v;
a = MInt(v);
return is;
}
friend constexpr std::ostream &operator<<(std::ostream &os, const MInt &a) {
return os << a.val();
}
friend constexpr bool operator==(MInt lhs, MInt rhs) {
return lhs.val() == rhs.val();
}
friend constexpr bool operator!=(MInt lhs, MInt rhs) {
return lhs.val() != rhs.val();
}
};
template<>
int MInt<0>::Mod = 998244353;
template<int V, int P>
constexpr MInt<P> CInv = MInt<P>(V).inv();
constexpr int P = 998244353;
using Z = MInt<P>;
std::vector<Z> fib(N), fib2(N), s(N);
void init() {
fib[1] = fib[2] = 1;
for(int i = 3; i < N; i++) {
fib[i] = fib[i - 1] + fib[i - 2];
}
for(int i = 1; i < N; i++) {
fib2[i] = fib[i] * fib[i];
s[i] = s[i - 1] + fib[i];
}
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
init();
TESTS {
int n;
cin >> n;
Z ans = 0;
for(int i = 1; i <= n; i++) {
ans += fib2[i] * Z(n + 1);
ans -= Z(2) * fib[i] * (s[n] - s[i - 1]);
}
cout << ans << "\n";
}
return 0;
}
I - 解码
分析
- 这题比较经典,注意处理向前循环移位越界的情况
#include<bits/stdc++.h>
using std::cin;
using std::cout;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using pii = std::pair<int, int>;
#define TESTS int _; std::cin >> _; while(_--)
constexpr i64 inf = 1E18, Md3 = 998244353, Md7 = 1e9 + 7;
constexpr double eps = 1E-9;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
TESTS {
int n, k;
cin >> n >> k;
std::string s;
cin >> s;
for(int i = 0; i < n; i++) {
if(s[i] >= 'a' && s[i] <= 'z') {
if(char(s[i] - k) < 'a') {
s[i] = 'z' - ('a' - s[i] + k) + 1;
} else {
s[i] -= k;
}
} else if(s[i] >= 'A' && s[i] <= 'Z') {
if(char(s[i] - k) < 'A') {
s[i] = 'Z' - ('A' - s[i] + k) + 1;
} else {
s[i] -= k;
}
}
}
cout << s << "\n";
}
return 0;
}
J - 选歌
分析
- 该题用到了优先队列,我们存储消耗大并且编号小的歌,依次取出队头元素,最后判断 h p hp hp 的值并输出答案即可
#include<bits/stdc++.h>
using std::cin;
using std::cout;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using pii = std::pair<i64, i64>;
#define TESTS int _; std::cin >> _; while(_--)
constexpr i64 inf = 1E18, Md3 = 998244353, Md7 = 1e9 + 7;
constexpr double eps = 1E-9;
struct cmp
{
bool operator()(pii p1, pii p2) {
if(p1.fi == p2.fi) {
return p1.se > p2.se;
}
return p1.fi < p2.fi;
}
};
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
TESTS {
i64 n, hp;
cin >> n >> hp;
std::priority_queue<pii, std::vector<pii>, cmp> pq;
std::vector<i64> b(n);
for(int i = 0; i < n; i++) {
cin >> b[i];
pq.push({b[i], i + 1});
}
std::vector<i64> ans;
while(pq.size() && hp > 0) {
auto [x, y] = pq.top();
pq.pop();
ans.push_back(y);
hp = std::max(hp - x, 0LL);
}
if(hp <= 0) {
cout << "YES\n";
cout << ans.size() << "\n";
for(auto x : ans) {
cout << x << " ";
}
cout << "\n";
} else {
cout << "NO\n";
}
}
return 0;
}
K - 晒卡
分析
- 由于需要从小到大输出编号,所以该题用 m a p map map 存储编号,并用 1 1 1 作存在的标记,最后遍历输出即可
#include<bits/stdc++.h>
using std::cin;
using std::cout;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using pii = std::pair<int, int>;
#define TESTS int _; std::cin >> _; while(_--)
constexpr i64 inf = 1E18, Md3 = 998244353, Md7 = 1e9 + 7;
constexpr double eps = 1E-9;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
TESTS {
int n;
cin >> n;
std::map<int, int> a1, b1;
std::vector<int> a(n), b(n);
for(int i = 0; i < n; i++) {
cin >> a[i];
a1[a[i]] = 1;
}
for(int i = 0; i < n; i++) {
cin >> b[i];
b1[b[i]] = 1;
}
std::vector<int> ans;
for(auto [x, y] : a1) {
if(b1.count(x)) {
ans.push_back(x);
}
}
cout << ans.size() << "\n";
if(ans.size() > 0) {
for(auto x : ans) {
cout << x << " ";
}
cout << "\n";
}
}
return 0;
}