随笔 - 164  文章 - 0  评论 - 4  阅读 - 9771

Codeforces Round 905 - div.3(A B C D E F)

Codeforces Round 905 (Div. 3)

div 3 都是思维题 qwq

A. Morning

模拟光标移动即可

void solve(){
string ss;
cin >> ss;
char ch = '1';
int ans = 0;
for(auto c : ss){
if(c != ch){
int x = c, y = ch;
if(c == '0') x = '9' + 1;
if(ch == '0') y = '9' + 1;
ans += abs(x - y);
ch = c;
}
++ ans;
}
cout << ans << '\n';
return ;
}

B. Chemistry

先统计每种字符出现的次数,再统计字符出现次数为奇数的个数 cnt,如果 cntk+1 则可以满足要求,反之不行

void solve(){
int n, k;
string ss;
cin >> n >> k >> ss;
vector<int> cnt(26, 0);
for(auto c : ss){
++ cnt[c - 'a'];
}
int shu[2] = {0, 0};
for(int i = 0; i < 26; ++ i)
if(cnt[i]) ++ shu[cnt[i] % 2];
if(k >= shu[1] - 1) cout << "YES\n";
else cout << "NO\n";
return ;
}

C. Raspberries

分类讨论
k = 2,3,5 时,只有给定的数变成其的倍数才行,记录改变所需最小值即
k = 4 需特判,k = 4 = 2 * 2,我们可以利用两个奇数 2 步实现,可以利用一奇一偶 1 步实现,也可以偶数但不是 4 的倍数 2 步实现,也可以奇数 1 三步实现

void solve(){
int n, ans = inf, k, a, shu[2] = {0, 0};
cin >> n >> k;
for(int i = 0; i < n; ++ i){
cin >> a;
ans = min(ans, (k - a % k) % k);
++ shu[a % 2];
}
if(k == 4){
if(shu[1] >= 2){
int t = 2 - min(2, shu[0]);
ans = min(ans, t);
}else if(shu[1] == 1){
if(shu[0] > 1) ans = 0;
else if(shu[0] == 1) ans = min(ans, 1);
else ans = min(ans, 3);
}else{
if(shu[0] >= 2) ans = 0;
}
}
cout << ans << '\n';
return ;
}

D. In Love

利用 multiset 存给定的线段 {l, r},用来找最大 l1 ;另外存一个 {r, l},用来找最小 r1
r1<l1 时满足题意,即为判断相距最远的两个线段能否相交

void solve(){
int q, l, r;
char ch;
cin >> q;
multiset<pii> x, y;
while(q --){
cin >> ch >> l >> r;
if(ch == '+'){
x.insert({l, r});
y.insert({r, l});
}else{
x.erase(x.find({l, r}));
y.erase(y.find({r, l}));
}
if(x.size() && x.rbegin() ->first > y.begin()->first)
cout << "YES\n";
else cout << "NO\n";
}
return ;
}

E. Look Back

由给出的数据范围可以知道,直接遍历求解显然会超数据范围,所以我们要尽量避免直接改变数值
对每一个下标的数,最终都可以表示为 a[i]×2xi

  • 如果 a[i1]a[i],那么 xi=xi1cnt,cnt 表示最小的 x 使得 a[i1]×2xa[i],且当相等时 cnt 应当减一,因为题目所求的为最小操作次数
  • 如果 a[i1]>a[i],那么 xi=xi1+cnt,cnt 表示表示最小的 x 使得 a[i1]a[i]×2x

所以另外开一个数组存 2xi 中的 xi 即可

void solve(){
int n;
cin >> n;
vector<int> a(n), b(n + 1, 0);
for(int i = 0; i < n; ++ i) cin >> a[i];
ll ans = 0;
for(int i = 1; i < n; ++ i){
if(a[i] >= a[i - 1]){
int t = a[i - 1], cnt = 0;
while(t < a[i]){
++ cnt; t <<= 1;
}
if(t > a[i]) -- cnt;
b[i] += max(0, b[i - 1] - cnt);
}else{
int t = a[i], cnt = 0;
while(a[i - 1] > t){
++ cnt; t <<= 1;
}
b[i] += b[i - 1] + cnt;
}
ans += b[i];
}
cout << ans << '\n';
return ;
}

F. You Are So Beautiful

注意到,我们选择的子序列在原数组中出现一次,那么一定有 al 是数 al 的首次出现,ar 是数 ar 的末次出现,如果不是的话,两边的相同数一定可以替代 al 或者 ar,此时该子序列不唯一

所以问题转化为找数的首次出现和末次出现,对于一个末次出现,对答案的贡献即为其位置前(包括当前位置)首次出现的数的个数

void solve(){
int n;
cin >> n;
vector<int> a(n);
map<int, int> last;// 记录最后一个出现的位置
for(int i = 0; i < n; ++ i){
cin >> a[i];
last[a[i]] = i;
}
map<int, int> pre;
ll ans = 0;
int cnt = 0;
for(int i = 0; i < n; ++ i){
if(pre[a[i]] == 0) ++ cnt;
++ pre[a[i]];
if(last[a[i]] == i) ans += cnt;
}
cout << ans << '\n';
return ;
}
posted on   Qiansui  阅读(313)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示