注意:
\color{red}{注意:}
注意: 个人博客传送门
A. Sum
思路:
- 基础的判断结构
时间复杂度: O ( 1 ) O(1) O(1)
void solve() {
int a, b, c;
std::cin >> a >> b >> c;
std::cout << ((a + b == c || b + c == a || a + c == b) ? "YES\n" : "NO\n");
}
B. Increasing
思路:
- 直接排序,比较相邻位置是否可能相等即可
时间复杂度: O ( n ) O(n) O(n)
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(a.begin(), a.end());
for (int i = 1; i < n; i++) {
if (a[i] == a[i - 1]) {
std::cout << "NO\n";
return ;
}
}
std::cout << "YES\n";
}
C. Stripes
思路:
- 由于题目保证了一定存在,那么我们只需要找到一个可能的一整行全部为
R
或者一整列都是一个字符B
,否则直接输出另外一个字符即可
时间复杂度: O ( 64 ) O(64) O(64)
void solve() {
std::vector<std::string> s(8);
for (int i = 0; i < 8; i++) {
std::cin >> s[i];
}
for (int i = 0; i < 8; i++) {
bool ok = true;
for (auto c : s[i]) {
if (c != 'R') {
ok = false;
break;
}
}
if (ok) {
std::cout << "R\n";
return ;
}
}
std::cout << "B\n";
}
D. Coprime
思路:
- 题目把 a i a_i ai 的范围设置到 ≤ 1 0 3 \le 10^3 ≤103,那么一定是一个 h a s h hash hash 之类的,我们把每个元素的位置存起来,然后暴力枚举互质的二元组即可
- 需要注意,一个从前向后,一个从后向前,这个可以使得互质二元组的和近可能的大
时间复杂度: O ( 1 0 6 ) O(10^6) O(106)
constexpr int N = 2E5 + 10;
void solve() {
int n;
std::cin >> n;
std::vector<int> a(N);
for (int i = 1; i <= n; i++) {
std::cin >> a[i];
}
std::vector<int> p(N);
for (int i = 1; i <= n; i++) {
p[a[i]] = i;
}
int ans = -1;
for (int i = 1000; i >= 1; i--) {
if (!p[i]) {
continue ;
}
for (int j = 1; j <= 1000; j++) {
if (p[j] && std::gcd(i, j) == 1) {
ans = std::max(ans, p[i] + p[j]);
}
}
}
std::cout << ans << "\n";
}
E. Scuza
思路:
- 用一个 m a x i max_i maxi 数组维护截止到第 i i i 个位置的最大数是多少,然后我们询问的时候直接二分查找下标即可,这样就可以得到
时间复杂度: O ( n + q ) O(n + q) O(n+q)
void solve() {
int n, q;
std::cin >> n >> q;
std::vector<i64> s(n + 1), max(n + 1);
for (int i = 1; i <= n; i++) {
int x;
std::cin >> x;
max[i] = std::max(1LL * x, max[i - 1]);
s[i] = s[i - 1] + x;
}
while (q--) {
i64 x;
std::cin >> x;
std::cout << s[std::upper_bound(max.begin() + 1, max.end(), x) - max.begin() - 1] << " ";
}
std::cout << "\n";
}
F. Smaller
思路:
- 我们要找到是否可能让
s
s
s 按照字典序排列小于
t
t
t 的方案,首先字典序的大小怎么判断?
- 要比较两个字符串谁小,我们要逐位比较,当比较完较短的字符串,仍然判断不出来谁大谁小,那么这时,就比较长度,长度大的较大,反之较小
- 然后,我们可以直接记录将 s s s 里的每个字符复制 k k k 遍,比较结果串里的首位字符,如果首位字符相等,且其他字符都相等,这时就比较长度即可
时间复杂度: O ( n × l e n ( s i ) ) O(n \times len(s_i)) O(n×len(si))
void solve() {
int n;
std::cin >> n;
char mins = 'a', mint = 'a';
char maxs = 'a', maxt = 'a';
i64 A = 1, B = 1;
for (int i = 0; i < n; i++) {
int d, k;
std::string s;
std::cin >> d >> k >> s;
for (auto c : s) {
if (d == 1) {
mins = std::min(mins, c);
maxs = std::max(maxs, c);
A += k;
} else {
mint = std::min(mint, c);
maxt = std::max(maxt, c);
B += k;
}
}
if (mins < maxt || (mins == maxt && mins == maxs && mint == maxt && A < B)) {
std::cout << "YES\n";
} else {
std::cout << "NO\n";
}
}
}
G. Orray
思路:
- 在 1 0 9 10^9 109 以内,也就 30 30 30 位,我们直接把最高位放在最前面,然后排序 30 30 30 次就行,每次更新当前的 s u m o r sum_{or} sumor
时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
void solve() {
int n;
std::cin >> n;
std::vector<int> a(n);
for (int i = 0; i < n; i++) {
std::cin >> a[i];
}
i64 p = 0;
for (int i = 0; i < std::min(n, 30); i++) {
std::sort(a.begin(), a.begin() + n - i, [&](int i, int j) {
return (i | p) < (j | p);
});
p |= a[n - i - 1];
}
for (int i = n - 1; i >= 0; i--) {
std::cout << a[i] << " \n"[i == 0];
}
}