目录
Codeforces Round #828 (Div. 3)
E1. Divisible Numbers (easy version)
A. Number Replacement
题意:
一个数组和一个字符串,数组元素变成字符串字符,问能不能变成。
思路:
map扫一遍就可以了
#include <bits/stdc++.h>
void solve() {
int n;
std::cin >> n;
std::vector<int>a(n);
std::unordered_map<int, int>mymap;
for (int i = 0; i < n; i++) {
std::cin >> a[i];
mymap[a[i]] = -1;
}
std::string s;
std::cin >> s;
for (int i = 0; i < n; i++) {
if (mymap[a[i]] == -1) {
mymap[a[i]] = i;
} else {
if (s[i] != s[mymap[a[i]]]) {
std::cout << "NO\n";
return ;
}
mymap[a[i]] = i;
}
}
std::cout << "YES\n";
//mymap.clear();
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t;
std::cin >> t;
while (t--) {
solve();
}
return 0;
}
复盘后发现甚至不需要用map,for数组元素相等的位置字符串对应位置的字符也应该相等,否则就不可能。
#include <bits/stdc++.h>
void solve() {
int n;
std::cin >> n;
std::vector<int>a(n);
for (int i = 0; i < n; i++) {
std::cin >> a[i];
}
std::string s;
std::cin >> s;
int flag = true;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (a[i] == a[j] && s[i] != s[j]) {
flag = false;
}
}
}
std::cout << (flag ? "YES\n" : "NO\n");
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t;
std::cin >> t;
while (t--) {
solve();
}
return 0;
}
B. Even-Odd Increments
每次把所有奇数元素+x或偶数元素+x,输出它的和
思路:
这里要注意一点,偶数+奇数=奇数,奇数+奇数=偶数,需要对计数器进行清零和加
#include <bits/stdc++.h>
#define int long long
void solve() {
int n, m;
std::cin >> n >> m;
std::vector<int>a(n);
int os = 0, es = 0, num1 = 0, num2 = 0;
for (int i = 0; i < n; i++) {
std::cin >> a[i];
if (a[i] & 1) os += a[i], num1++;
else es += a[i], num2++;
}
while (m--) {
int op;
std::cin >> op;
if (op == 0) {
int x;
std::cin >> x;
es += num2 * x;
if (x & 1)num1 += num2, num2 = 0;
} else {
int x;
std::cin >> x;
os += num1 * x;
if (x & 1)num2 += num1, num1 = 0;
}
std::cout << os + es << "\n";
}
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t;
std::cin >> t;
while (t--) {
solve();
}
return 0;
}
C. Traffic Light
一个字符串中字符分别代表红,绿,黄,给定一个字符代表当前红绿灯状态,问最大什么时候才能通行
思路:
2*字符串即两个周期涵盖了所有情况,找最大值就行了
#include <bits/stdc++.h>
#define int long long
void solve() {
int n;
char ch;
std::cin >> n >> ch;
std::string s;
std::cin >> s;
std::string t = s;
t += s;
int f = 0, ans = -1;
for (int i = (int)t.size() - 1; i >= 0 ; i--) {
if (t[i] == 'g') f = i;
if (t[i] == ch) ans = std::max(ans, f - i);
}
std::cout << ans << "\n";
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t;
std::cin >> t;
while (t--) {
solve();
}
return 0;
}
D. Divisibility by 2^n
有若干个操作,a[i]*i,每个数最多被乘一次,最少多少次把数组的乘积和能被2^n整除
思路:
如果数组所有元素有至少n个2的因子数那么一定能被2^n整除,否则在1~n中找2因子的数量,贪心地去选因子数最大的。
#include <bits/stdc++.h>
#define int long long
#define lowbit(x) (x)&-(x)
void solve() {
int n;
std::cin >> n;
std::vector<int> a(n);
std::vector<int> d;
int cnt = 0;
for (int i = 0; i < n; i++) {
std::cin >> a[i];
int k = a[i];
while (k % 2 == 0) {
k /= 2;
cnt++;
}
int p = i + 1;
int m = 0;
while (p % 2 == 0) {
p /= 2;
m++;
}
if (m) {
d.emplace_back(m);
}
}
if (cnt >= n) {
std::cout << 0 << "\n";
return;
}
std::sort(d.begin(), d.end(), std::greater<int>());
int j = 0, ans = 0, f = n - cnt, len = d.size();
while (j < len && f) {
if (d[j] <= f) {
ans++;
f -= d[j];
}
j++;
}
if (f) std::cout << -1 << "\n";
else std::cout << ans << "\n";
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t;
std::cin >> t;
while (t--) {
solve();
}
return 0;
}
学过佬的代码(结合__builtin_ctz( ) 太细了!!):
#include <bits/stdc++.h>
void solve() {
int n;
std::cin >> n;
std::vector<int> a(n);
for (int j = 0; j < n; j++) {
std::cin >> a[j];
}
std::vector<int> b(n), c(n);
for (int j = 0; j < n; j++) {
b[j] = __builtin_ctz(a[j]);
c[j] = __builtin_ctz(j + 1);
}
int cnt = 0;
for (int j = 0; j < n; j++) {
cnt += b[j];
}
std::sort(c.begin(), c.end(), std::greater<int>());
int ans = 0;
for (int j = 0; j < n; j++) {
if (cnt < n) {
cnt += c[j];
ans++;
}
}
if (cnt < n) {
std::cout << -1 << "\n";
} else {
std::cout << ans << "\n";
}
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t;
std::cin >> t;
while (t--) {
solve();
}
return 0;
}
E1. Divisible Numbers (easy version)
a,b,c,d,找到一组x,y(a<x<=c,b<y<=d),使x*y能整除a*b
暴力枚举即可
#include <bits/stdc++.h>
#define int long long
#define lowbit(x) (x)&-(x)
void solve() {
int a, b, c, d;
std::cin >> a >> b >> c >> d;
int cur = a * b;
int i = a + 1;
while (i <= c) {
int k = cur / std::__gcd(cur, i);
int j = (k + b - 1 + 1) / k * k;
if (j > b && j <= d) {
std::cout << i << " " << j << "\n";
return ;
}
i++;
}
std::cout << "-1 -1\n";
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t;
std::cin >> t;
while (t--) {
solve();
}
return 0;
}