Practice.
A. Number Replacement
题意
给定一个序列,一个字母可以映射到任意一个数字,但要求一个字母只能映射到一个数字,一个数字可以映射到多个字母。输出是否合法。
思路
简单,我们用哈希即可。用
时间复杂度:
对应AC代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
const int N = 1e6 + 10, inf = 0x3f3f3f3f3f3f3f3f, mod = 998244353;
void solve() {
int n;
cin >> n;
vector<int> a(n);
for(int i=0;i<n;i++) cin >> a[i];
string s;
cin >> s;
map<int, char> mp;
bool f = true;
for(int i=0;i<n;i++){
if(mp[a[i]] > 0 && mp[a[i]] != s[i]) f = false;
mp[a[i]] = s[i];
}
cout << (f ? "YES\n" : "NO\n");
}
signed main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
//init();
int t;
cin >> t;
while(t --) solve();
}
水.jpg
B. Even-Odd Increments
题意
给定一个序列,含有奇数和偶数,定义操作如下:
表示将 添加到所有偶数上; 表示将 添加到所有奇数上。
在每次操作后,输出总和。前面的操作会影响后面的值。
思路
显然,我们只需统计当前序列有多少偶数即可。
设偶数的个数为
显然,我们不需要在每次操作后遍历找偶数个数,而是考虑下面的规律:
偶数加奇数为奇数;
奇数加奇数为偶数。
因而,若出现将奇数加在奇数上的情况,那么
时间复杂度:
对应AC代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
const int N = 1e6 + 10, inf = 0x3f3f3f3f3f3f3f3f, mod = 998244353;
void solve() {
int n, q;
cin >> n >> q;
vector<int> a(n); //注意一下偶数和奇数的相加即可
int even = 0, sum = 0;
for(int i=0;i<n;i++){
cin >> a[i];
sum += a[i];
if(a[i] % 2 == 0) even ++;
}
while(q --){
int t, v;
cin >> t >> v;
if(t % 2 == 0){ //加到偶数上
sum += even * v;
cout << sum << '\n';
if(v % 2 == 1) even = 0; //偶加奇
}else{ //加到奇数上
sum += (n - even) * v;
cout << sum << '\n';
if(v % 2 == 1) even = n; //奇加奇
}
}
}
signed main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
//init();
int t;
cin >> t;
while(t --) solve();
}
偏模拟的思维题
C. Traffic Light
题意
定义三种交通信号灯:
思路
如上,我们只需遍历所有
至于距离,数据范围貌似可以允许我们暴力往后搜,但后缀数组会出手。
我们维护后缀数组,
那么,查询的复杂度即为
时间复杂度:
对应AC代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
const int N = 1e6 + 10, inf = 0x3f3f3f3f3f3f3f3f, mod = 998244353;
void solve() {
int n;
char c;
cin >> n >> c;
string s;
cin >> s;
s = " " + s + s;
n *= 2;
vector<int> suf(n + 1);
suf[n] = -1;
for(int i=n - 1;i>=1;i--){
if(s[i] == 'g') suf[i] = i;
else suf[i] = suf[i + 1];
}
int mx = 0;
for(int i=0;i<n;i++){
if(s[i] == c) mx = max(mx, suf[i] - i);
}
cout << mx << '\n';
}
signed main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
//init();
int t;
cin >> t;
while(t --) solve();
}
可能就真的能暴力((
D. Divisibility by 2^n
题意
给定一个长度为
思路
首先,乘上奇数绝对没什么用,所以我们只需考虑偶数。
观察偶数的递推性以及二进制下的规律,我们不难发现所有的偶数都是一个
上述没必要乘上偶数,毕竟那就是
因而,我们自然希望我们能在一次操作中乘上尽可能多的
这个
那么,我们不妨去枚举
在加之前,我们判断一下当前能除多少个
时间复杂度:
对应AC代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
const int N = 1e6 + 10, inf = 0x3f3f3f3f3f3f3f3f, mod = 998244353;
void solve() {
int n;
cin >> n;
int cnt = 0;
for(int i=0;i<n;i++){
int cur;
cin >> cur;
while(cur % 2 == 0){
cur /= 2;
cnt ++;
}
}
int mx = 1, cur = 2;
while(true){
if(cur * 2 > n) break;
mx ++;
cur *= 2;
}
int ans = 0;
for(int i=mx;i>=1;i--){
for(int j=1;pow(2, i)*j<=n;j+=2){ //奇数倍
if(cnt >= n) break;
cnt += i;
ans ++;
}
if(cnt >= n) break;
}
cout << (cnt >= n ? ans : -1) << '\n';
}
signed main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
//init();
int t;
cin >> t;
while(t --) solve();
}
奇怪的清晰思路增加了
E1. Divisible Numbers (easy version)
详见E2,区别是本题的数据范围小
E2. Divisible Numbers (hard version)
题意
给定
思路
首先,我们不难发现,
那么我们来考虑
那么,我们只需枚举所有的因数,然后,我们也可以用
但是,枚举
因而,
时间复杂度:
对应AC代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
const int N = 1e6 + 10, inf = 0x3f3f3f3f3f3f3f3f, mod = 998244353;
vector<int> fact(int x) {
vector<int> facts;
int sq = (int) sqrt(x);
for (int i = 1; i < sqrt(x); i++) {
if (x % i == 0) facts.emplace_back(i), facts.emplace_back(x / i);
}
if (sq * sq == x) facts.emplace_back(sq);
return facts;
}
void solve() {
int a, b, c, d;
cin >> a >> b >> c >> d;
vector<int> factA = fact(a), factB = fact(b);
bool f = false;
for (int i: factA) {
for (int j: factB) {
int bx = i * j, by = a * b / (i * j);
int x = ((int) ceil((double) a / (double) bx) + (a % bx == 0 ? 1 : 0)) * bx,
y = ((int) ceil((double) b / (double) by) + (b % by == 0 ? 1 : 0)) * by;
if (x <= c && y <= d) {
cout << x << ' ' << y << '\n';
f = true;
break;
}
}
if (f) break;
}
if (!f) cout << -1 << ' ' << -1 << '\n';
}
signed main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
//init();
int t;
cin >> t;
while (t --) solve();
}
一开始还想着贪心,似也做不出来,淦
- 本文链接 https://floating-ocean.github.io/blog_old/posts/3533911585/
- 版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!