Codeforces Round 913 (Div. 3)
CF1907总结
A. Rook
题面翻译
给出车在国际象棋棋盘中的位置,输出其可到达的坐标(不必在意顺序)。
车可以横着或竖着走任意格数。

分析
题意明了,输出车所在行和列所有格子的序号(除车所在位置外)。
code
#include <bits/stdc++.h>
using namespace std;
int t;
void solve()
{
string x;
cin>>x;
int a=x[0];
int b=x[1]-'0';
for(int i=1;i<=8;i++) if(i!=b) cout<<(char)a<<i<<"\n";
for(int i='a';i<='h';i++) if(a!=i) cout<<(char)i<<b<<"\n";
}
int main ()
{
cin>>t;
while(t--) solve();
return 0;
}
B. YetnotherrokenKeoard
题面翻译
Polycarp 的笔记本键盘坏了。
现在,当他按下 'b' 键时,它的行为类似于退格键:删除已输入字符串中最后一个小写字母。如果已输入字符串中没有小写字母,则完全忽略该按键。
类似地,当他按下 'B' 键时,它删除已输入字符串中最后一个大写字母。如果已输入字符串中没有大写字母,则完全忽略该按键。
给定一个按键序列,输出处理所有按键后的结果。
分析
用两个栈分别存下大写和小写字母的位置,每次删除时若栈非空则取对应栈顶位置删除。
code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5;
int n,m,t,i1[N],i2[N];
char a[N];
string s;
void solve()
{
cin>>s;
n=s.size();
int t1=0,t2=0;
for(int i=0;i<n;i++)
{
a[i]=0;
int x=s[i];
if(x=='b')
{
if(t1)
{
a[i1[t1--]]=0;
}
}
else if(x=='B')
{
if(t2)
{
a[i2[t2--]]=0;
}
}
else
{
if(x>='a'&&x<='z') i1[++t1]=i;
if(x>='A'&&x<='Z') i2[++t2]=i;
a[i]=x;
}
}
for(int i=0;i<n;i++) if(a[i]!=0) cout<<a[i];
cout<<"\n";
}
int main ()
{
cin>>t;
while(t--) solve();
return 0;
}
C. Removal of Unattractive Pairs
题面翻译
有一个长为 \(n\) 的字符串,每次可以删除相邻两个不同的字符,问删除若干次最终可能的最短长度
分析
这让我想到一种类似的题,只不过是把题目和解法反过来。
已知小写字母组成的长度为 \(n\) 的字符串,求个数超过 \(n/2\) 的小写字母,保证至多至少有一个,\(1<n<1\times10^8\)。
- 直接排序,取最中间的那个数,复杂度为 \(O(n\log{n})\)。
- 用一个桶统计个数,再找出满足的那个,复杂度为 \(O(n)\)。
还能不能更快呢?于是聪明的你一定能想到每次读入后删掉两个不同的字母,没错,删掉两个不同的字母后,永远不会影响我们要求的答案。用我们要求的答案来和其他字母相删,最后一定有剩余。这样就能做到更快的线性复杂度求出答案了。
接下来回到这道题,考虑删除难想,不如考虑不删除的情况:
- 字符串为空。
- 只剩下一个字符。
那就好了,相邻的限制已经无所谓了,我们可以知道最短的长度就是让数量最多的字母与其他字母互删,得到剩下的数量 \(num\),还要注意 \(n\) 如果是奇数的话一定会剩下一个,最后答案就是 \(\max(num,n\bmod2)\)。
code
#include <bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,t,a[N];
string s;
void solve()
{
cin>>n>>s;
for(int i=0;i<n;i++) a[s[i]-'a']++;
int ma=0;
for(int i=0;i<26;i++) ma=max(ma,a[i]),a[i]=0;
cout<<max(n&1,ma*2-n)<<"\n";
}
int main ()
{
cin>>t;
while(t--) solve();
return 0;
}
D. Jumping Through Segments
题面翻译
数轴上有 \(n\) 条线段,第 \(i\) 条线段的范围是 \([l_i,r_i]\)。
开始时在原点,每次可以跳至多 \(k\) 的距离,但是在第 \(i\) 次跳跃后一定要站在第 \(i\) 条线段上。
求出最小的 \(k\) 使得你可以跳到第 \(n\) 条线段上。
分析
求最小的 k 值,已知上界和下界,不难看出可以用二分答案,重点思考如何进行判断。
考虑每一步可以到达的区间,第一步可到达 \([-k,k]\) 如果和第二段没有交集,那肯定不满足要求,如果有交集说明下一步要从这交集开始跳,于是范围就变为 \([l-k,r+k]\)。于是我们只需要一直求交集判断下一步是否有交集直到最后。
总复杂度为 \(O(n\log{k})\)。
code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5;
int n,m,t,a[N],b[N];
int check(int k)
{
int l=0,r=0;
for(int i=1;i<=n;i++)
{
l-=k,r+=k;
if(l>b[i]||r<a[i]) return 1;
l=max(l,a[i]),r=min(r,b[i]);
}
return 0;
}
void solve()
{
cin>>n;
int l=0,r=1,mid;
for(int i=1;i<=n;i++) cin>>a[i]>>b[i],r=max(r,b[i]);
while(l<r)
{
mid=(l+r)>>1;
if(check(mid)) l=mid+1;
else r=mid;
}
cout<<l<<"\n";
}
int main ()
{
cin>>t;
while(t--) solve();
return 0;
}
E. Good Triples
题面翻译
给定一个整数 \(n\),我们称三元组 \((a,b,c)\) 是“好的”,当且仅当 \(a+b+c=n\) 并且 \(digsum(a)+digsum(b)+digsum(c)=digsum(n)\)。这里的 \(digsum(x)\) 指的是 \(x\) 各个数位之和。
并且三元组的顺序也很重要。例如 \((4,12,10)\) 和 \((10,12,4)\) 不是相同的三元组。
求不同三元组的数量。
分析
容易看出,如果没有进位,则一定能满足条件,如果产生进位,则 \(digsum(a)+digsum(b)+digsum(c)>digsum(n)\)。所以每一位分开来考虑,计算贡献。
code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
int n,m,t,a[N];
void solve()
{
string s;
cin>>s;
n=s.size();
ll ans=1;
for(int i=0;i<n;i++) ans*=a[s[i]-'0'];
cout<<ans<<"\n";
}
int main ()
{
a[0]=1;
for(int i=1;i<=9;i++) a[i]=a[i-1]+i+1;
cin>>t;
while(t--) solve();
return 0;
}
F. Shift and Reverse
题面翻译
给定一个整数数组 \(a_1,a_2, \ldots,a_n\),你可以对其进行两种操作:
- 移位:将最后一个元素移动到第一位,并将其他元素后移,得到数组 \(a_n,a_1,a_2,\ldots,a_{n-1}\)。
- 翻转:将整个数组翻转过来,得到数组 \(a_n,a_{n-1},\ldots,a_2,a_1\)。
你的任务是用最少得操作次数来对使数组非递增排序,做不到就输出 -1。
分析
从两个操作入手,先考虑移位,将最后一个移动到第一位,有一种比较好想的方法,把数组看成一个环,数组第一个元素位置为 \(i\)。这样操作就变为:
- 移位:按方向将 \(i\) 移动一位。
- 翻转:改变方向,从逆时针改为顺时针,从逆时针改为顺时针。
题目就变成:已知一个环,最初 \(i\) 为 \(1\),找到一个位置 \(i\),满足从 \(i\) 开始按方向走使回到 \(i\) 前经过的数非递增。答案为 \(i\) 移动的距离加上改变方向的次数。
于是,可将数组复制一倍,从最后开始向前遍历,找到满足条件的 \(i\),计算答案。翻转相当于改变方向,那么最多只要改变一次,分两种情况,刚开始就翻转或最后再翻转,分别处理。还有一点 \(n=1\) 时答案为 \(0\) 要特判一下。
code
// LUOGU_RID: 140107120
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5,inf=0x3f3f3f3f;
int n,m,t,a[N];
int work()
{
for(int i=1;i<=n;i++) a[i+n]=a[i];
int ans=inf,cnt=1;
for(int i=2*n-1;i>=1;i--)
{
if(a[i]<=a[i+1]) cnt++;
else cnt=1;
if(cnt==n)
{
ans=min(ans,n-i+1);
break;
}
}
cnt=1;
for(int i=2*n-1;i>=1;i--)
{
if(a[i]>=a[i+1]) cnt++;
else cnt=1;
if(cnt==n)
{
ans=min(ans,n-i+2);
break;
}
}
return ans;
}
void solve()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
if(n==1)
{
cout<<0<<"\n";
return ;
}
int ans=work();
reverse(a+1,a+n+1);
ans=min(ans,work()+1);
if(ans==inf) cout<<-1<<"\n";
else cout<<ans<<"\n";
}
int main ()
{
cin>>t;
while(t--) solve();
return 0;
}
Codeforces Round 913 (Div. 3)的更多相关文章
- Codeforces Round #366 (Div. 2) ABC
Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...
- Codeforces Round #354 (Div. 2) ABCD
Codeforces Round #354 (Div. 2) Problems # Name A Nicholas and Permutation standard input/out ...
- Codeforces Round #368 (Div. 2)
直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...
- cf之路,1,Codeforces Round #345 (Div. 2)
cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅..... ...
- Codeforces Round #279 (Div. 2) ABCDE
Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems # Name A Team Olympiad standard input/outpu ...
- Codeforces Round #262 (Div. 2) 1003
Codeforces Round #262 (Div. 2) 1003 C. Present time limit per test 2 seconds memory limit per test 2 ...
- Codeforces Round #262 (Div. 2) 1004
Codeforces Round #262 (Div. 2) 1004 D. Little Victor and Set time limit per test 1 second memory lim ...
- Codeforces Round #371 (Div. 1)
A: 题目大意: 在一个multiset中要求支持3种操作: 1.增加一个数 2.删去一个数 3.给出一个01序列,问multiset中有多少这样的数,把它的十进制表示中的奇数改成1,偶数改成0后和给 ...
- Codeforces Round #268 (Div. 2) ABCD
CF469 Codeforces Round #268 (Div. 2) http://codeforces.com/contest/469 开学了,时间少,水题就不写题解了,不水的题也不写这么详细了 ...
- 贪心+模拟 Codeforces Round #288 (Div. 2) C. Anya and Ghosts
题目传送门 /* 贪心 + 模拟:首先,如果蜡烛的燃烧时间小于最少需要点燃的蜡烛数一定是-1(蜡烛是1秒点一支), num[g[i]]记录每个鬼访问时已点燃的蜡烛数,若不够,tmp为还需要的蜡烛数, ...
随机推荐
- Python入门--字符串
字符串的使用和C语言 .java中一致 .使用" "(双引号)并且字符串可以与数字相乘,表示我使用这个字符串次数 字符串的连接:'+' Python中的变量直接赋值即可 ,如果赋予 ...
- P5318 查阅文献
题意大概意思就是分别用dfs与bfs遍历一个图,特殊要求是从编号小的点开始遍历. 用邻接表存图,至今我也没想明白怎么才可以从编号小的点开始遍历,明白是排序,但是不知道如何排序,题解中的排序方法是:按照 ...
- WPF应用开发之附件管理
在我们之前的开发框架中,往往都是为了方便,对附件的管理都会进行一些简单的封装,目的是为了方便快速的使用,并达到统一界面的效果,本篇随笔介绍我们基于SqlSugar开发框架的WPF应用端,对于附件展示和 ...
- Linux速查备忘手册
速查手册 网盘文档PDF资料: 链接: https://pan.baidu.com/s/111rqKfPaAiOHSHDo1SnckA 提取码: mhkv 1. 2. 3. 4. 5. ...
- 聊一聊 .NET高级调试 中的一些内存术语
一:背景 1. 讲故事 在高级调试的旅程中,经常会有一些朋友问我什么是 工作集(内存),什么是 提交大小,什么是 Virtual Size, 什么是 Working Set ...截图如下: 既然有很 ...
- 生成模型的两大代表:VAE和GAN
生成模型 给定数据集,希望生成模型产生与训练集同分布的新样本.对于训练数据服从\(p_{data}(x)\):对于产生样本服从\(p_{model}(x)\).希望学到一个模型\(p_{model}( ...
- [ARC168E] Subsegments with Large Sums
题目链接 看到严格选 \(k\) 个,不难想到 WQS二分.定义 \(f(x)\) 为分成 \(x\) 段,最多有多少个超过 \(S\) 的.然后你会发现他不是凸的.因为他有很多平段,比如把两个很小的 ...
- Git恢复删除的文件,一行命令就可以啦~
情况一:删除或者修改了某个文件,但是没有add # 单个 git checkout filename # 多个 git checkout . 情况二:删除或者修改了某个文件,已经add,但是没有com ...
- Java 面试题及答案整理(2021最新版)持续更新中~~~
2021年java实习校招秋招春招 后端 知识点及面试题(持续更新) Java面试总结汇总,整理了包括Java基础知识,集合容器,并发编程,JVM,常用开源框架Spring,MyBatis,数据库,中 ...
- 劫持 PE 文件:新建节表并插入指定 DLL 文件
PE格式简介 PE(Portable Executable)格式,是微软Win32环境可移植可执行文件(如exe.dll.vxd.sys和vdm等)的标准文件格式.PE格式衍生于早期建立在VAX(R) ...