A.YES or YES?
题 意 : 题意: 题意:
就是判断给定的字符串是否是 y e s yes yes
思 路 : 思路: 思路:
将字符串全转为大写,判断是否和 Y E S YES YES相等
C o d e Code Code
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
using ull = unsigned long long;
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int _;
for (cin >> _; _; _ --) {
string s;
cin >> s;
for (auto &si : s)
si = toupper(si);
cout << (s == "YES" ? s : "NO") << "\n";
}
return 0;
}
B.ICPC Balloons
题 意 : 题意: 题意:
每个字母第一次出现时答案 + 2 +2 +2,后面再出现就 + 1 +1 +1
思 路 : 思路: 思路:
开一个数组记录出现次数,答案为出现次数大于1的字母次数+1的累计和
C o d e Code Code
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
using ull = unsigned long long;
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int _;
for (cin >> _; _; _ --) {
int n;
cin >> n;
string s;
cin >> s;
vector<int> cnt(26, 0);
for (auto &si : s)
cnt[si - 'A'] ++;
int ans = 0;
for (int i = 0; i < 26; i ++)
if (cnt[i])
ans += cnt[i] + 1;
cout << ans << "\n";
}
return 0;
}
C.Cypher
题 意 : 题意: 题意:
给定你密码锁的最终状态,和操作次数以及每次的操作,求密码锁最初状态
思 路 : 思路: 思路:
每次操作做相反的操作就可以达到初始状态
C o d e Code Code
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
using ull = unsigned long long;
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int _;
for (cin >> _; _; _ --) {
int n;
cin >> n;
vector<int> a(n);
for (int &ai : a)
cin >> ai;
for (int i = 0; i < n; i++) {
int ops;
cin >> ops;
string op;
cin >> op;
for (auto opi : op)
if (opi == 'D')
a[i] ++, a[i] %= 10;
else
a[i] --, a[i] = (a[i] + 10) % 10;
}
for (int i = 0; i < n; i ++)
cout << a[i] << " \n"[i == n - 1];
}
return 0;
}
D.Double Strings
题 意 : 题意: 题意:
给 n n n个字符串,判断第 i i i个字符串能否由其他字符串拼接组成,若有输出 1 1 1,否则输出 0 0 0
思 路 : 思路: 思路:
观察到每个字符串的长度不超过 8 8 8,故可使用枚举子串+ s e t set set查找,时间复杂度为 O ( n × l o g ( n ) ) O(n \times log(n)) O(n×log(n))
C o d e Code Code
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
using ull = unsigned long long;
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int _;
for (cin >> _; _; _ --) {
int n;
cin >> n;
set<string> ex;
vector<string> s(n);
for (auto &si : s) {
cin >> si;
ex.insert(si);
}
string ans = "";
for (int i = 0; i < n; i ++) {
bool ok = false;
for (int j = 1; j < int(s[i].size()); j ++)
if (ex.count(s[i].substr(0, j)) && ex.count(s[i].substr(j))) {
ok = true;
break;
}
ans += (ok ? '1' : '0');
}
cout << ans << "\n";
}
return 0;
}
E.Mirror Grid
题 意 : 题意: 题意:
要求整个图形是中心对称的,可以把 0 0 0变成 1 1 1也可以把 1 1 1变成 0 0 0,求最小操作次数
思 路 : 思路: 思路:
每次枚举一个正方形的一条边,然后计算 0 0 0和 1 1 1的个数,若都不为 0 0 0,则将个数少的变成个数多的
C o d e Code Code
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
using ull = unsigned long long;
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int _;
for (cin >> _; _; _ --) {
int n;
cin >> n;
vector<string> s(n);
for (auto &si : s)
cin >> si;
vector<vector<int>> vis(n, vector<int> (n));
auto get = [&] (int x, int y) -> void {
int ones = 0, zeros = 0;
int dx[4] = {x, y, n-1-x, n-1-y}, dy[4] = {y, n-1-x, n-1-y, x};
for (int i = 0; i < 4; i ++) {
int xx = dx[i], yy = dy[i];
if (s[xx][yy] == '1') {
ones ++;
} else {
zeros ++;
}
}
if (ones == 0 || zeros == 0)
return ;
int ok = int(zeros <= ones);
for (int i = 0; i < 4; i ++)
if (s[dx[i]][dy[i]] == '1' - ok)
vis[dx[i]][dy[i]] = 1;
return ;
};
for (int i = 0; i < (n + 1) / 2; i ++)
for (int j = i; j <= (n - 1) - i; j ++)
get(i, j);
int ans = 0;
for (auto vi : vis)
for (auto vij : vi)
ans += vij;
cout << ans << "\n";
}
return 0;
}
// 推导
/*
11100
11011
01011
10011
11000
11101
11111
11011
11111
11111
0,0 -> 0,n-1 -> n-1,n-1 -> n-1,0
0,1 -> 1,n-1 -> n-1,n-2 -> 1,0
0,2 -> 2,n-1 -> n-1,2 -> 2,n-1
1,1 -> 1,n-1-1 -> n-1-1,n-1-1 -> n-1-1,1
2,2 -> 2,n-1-2 -> n-1-2,n-1-2 -> n-1-2,2
*/
F.Yet Another Problem About Pairs Satisfying an Inequality
题 意 : 题意: 题意:
给一个数组 a a a,求满足 a i < i < a j < j a_{i} < i < a_{j} < j ai<i<aj<j的个数
思 路 : 思路: 思路:
在读入数据时,将 a i < i a_{i} < i ai<i的数据放进数组,然后排序,每次二分查找边界,时间复杂度 O ( n × l o g ( N ) ) O(n \times log(N)) O(n×log(N))
C o d e Code Code
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
using ull = unsigned long long;
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int _;
for (cin >> _; _; _ --) {
int n;
cin >> n;
vector<pair<int, int>> a;
for (int i = 1; i <= n; i ++) {
int x;
cin >> x;
if (x < i)
a.push_back({x, i});
}
sort(a.begin(), a.end());
a.push_back({1e9 + 5, 1e9 + 10});
i64 ans = 0;
for (int i = 0, j = 0; i < int(a.size()); i ++) {
int l = i + 1, r = (int)a.size() - 1;
while (l < r) {
int mid = (l + r) >> 1;
if (a[mid].first > a[i].second)
r = mid;
else
l = mid + 1;
}
ans += (int)a.size() - r - 1;
}
cout << ans << "\n";
}
return 0;
}
G.Good Key, Bad Key
题 意 : 题意: 题意:
给 n n n个门,每打开一个门可以获得 a i a_{i} ai的价值,可以使用好钥匙和坏钥匙打开门,使用好钥匙要花费 k k k,使用坏钥匙会使 [ i , n ] [i,n] [i,n]后面的门内价值减少一半,求最大价值
思 路 : 思路: 思路:
考虑使用好坏钥匙的顺序,先使用好钥匙再使用坏钥匙,所获得价值为 a i + ⌊ a i + 1 / 2 ⌋ − k a_{i} + \lfloor a_{i + 1} / 2 \rfloor - k ai+⌊ai+1/2⌋−k,先使用坏钥匙再使用好钥匙,所获得价值为 ⌊ a i / 2 ⌋ + ⌊ a i + 1 / 2 ⌋ − k \lfloor a_{i} / 2 \rfloor + \lfloor a_{i + 1} / 2 \rfloor - k ⌊ai/2⌋+⌊ai+1/2⌋−k,可以观察到先使用好钥匙所获得的价值一定更好,故枚举每次使用好钥匙的门,在此之前全用好钥匙,后面全用坏钥匙,坏钥匙最多可以使用31把,剩下的价值全部为0
C o d e Code Code
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
using ull = unsigned long long;
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int _;
for (cin >> _; _; _ --) {
i64 n, k;
cin >> n >> k;
vector<i64> a(n + 1);
for (int i = 1; i <= n; i ++) {
cin >> a[i];
a[i] += a[i - 1];
}
i64 res = 0;
for (int i = 0; i <= n; i ++) {
i64 sum = a[i] - k * i;
for (int j = 1; j <= 32 && i + j <= n; j ++)
sum += (a[j + i] - a[j + i - 1]) >> j;
res = max(res, sum);
}
cout << res << "\n";
}
return 0;
}