Codeforces Round #809 (Div. 2)
给了t个询问,n个数Ai,又给了一个数为m,原来字符串为一连串的B,有两个操作第一个操作使第Ai个变为A,第二个操作使(M+1-Ai)变为A,使其字典序最小,肯定是比一下看那个在前面,记录一下即可。
1
4 5
1 1 3 1
注意的使我们要判断一下是否有重复操作进行了操作1以后,再次遇到这个数时进行操作二,先进行2时再进行1。
查看代码:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
char a[60];
bool st[60];
int b[60];
int main()
{
int t;
cin >> t;
while(t--)
{
int n,m;
cin >> n>>m;
for(int i=1;i<=m;i++)
{
a[i]='B';
st[i]=false;
}
for(int i=1;i<=n;i++)
{
cin >> b[i];
}
for (int i = 1; i <= n; i ++ )
{
if(b[i]<=m+1-b[i]&&!st[b[i]])
{
a[b[i]]='A';
st[b[i]]=true;
}
else if(b[i]>m+1-b[i]&&!st[m+1-b[i]])
{
a[m+1-b[i]]='A';
st[m+1-b[i]]=true;
}else if(st[b[i]])
{
a[m+1-b[i]]='A';
}else if(st[m+1-b[i]])
{
a[b[i]]='A';
}
}
for (int i = 1; i<=m; i++ )
cout << a[i];
cout << endl;
}
return 0;
}
这题真的是道好题,给了n个数Ai,每个数代表了一个颜色,当前Ai只能放在前一个的左右两边或者上边,判断一下每种颜色能达到的最大高度。首先是数据转图形。
7
1 2 3 1 2 3 1
input:
3 2 2 0 0 0 0
可以发现只要中间差两个数就可以形成高塔,很好wa了。再讨论离得更远些。
相离偶数个就可以,但是我们碰到了极端情况也就是最优解的选取,怎样判断最优解,这里给一个小证明即从头开始取即是最优解。
6
4 2 2 2 4 4
查看代码:
#include<iostream>
using namespace std;
const int N=1e5+10;
struct
{
int x;
int y;
}e[N];
bool st[N];
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
int z;
cin>>z;
if(!st[z])
{
e[z].x=i;
e[z].y++;
st[z]=1;
}else if((i+1-e[z].x)%2==0)
{
e[z].x=i;
e[z].y++;
}
}
for(int i=1;i<=n;i++)
cout<<e[i].y<<' ';
cout<<endl;
for(int i=1;i<=n;i++)
{
st[i]=0;
e[i].y=0;
}
}
return 0;
}
给了n个数Ai,代表每个位置柱子的初始高度,可以进行操作使柱子的高度加一使其cool(Ai-1<Ai&&Ai+1<Ai)既是山峰,求每个样例最多山峰的最小操作数。
3
2 1 2
6
3 1 4 5 5 2
8
4 2 1 3 5 3 6 1
当长度为奇数时
比如第一个样例,下标i为1-n,那么下标为偶数的点必需是凉爽点,这是直接加起来就行
当长度为偶数时
可以发现第2,3个,第4,5个,第6,7个.....中选一个作为凉爽点,而且不能有相邻
如果第3个为凉爽点,那么后面的就一定是5,7,9...
如果第5个为凉爽点,那么后面的就一定是7,9,11...
也就是从某一处开始选的是右边奇数的,那么后面一定都是选右边奇数,而前边一定都是选左边偶数的
那么记录选左边的从前到后的和x[i],以及选右边的从后到前的和y[i]
答案就是max(x[i]+y[i+1])
查看代码
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
#define inf (1ll<<52)
const int N=1e5+10;
long long a[N];
long long c[N];
long long d[N];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
for(int i=2;i<=n-1;i+=2)
{
c[i]+=c[i-2]+max(0ll,max(a[i-1],a[i+1])-a[i]+1);
}
if(n&1)
{
printf("%lld\n",c[n-1]);
memset(c,0,sizeof c);
memset(d,0,sizeof d);
memset(a,0,sizeof a);
continue;
}
for(int i=n-1;i>1;i-=2)
d[i]=d[i+2]+max(0ll,max(a[i-1],a[i+1])-a[i]+1);
long long res=inf;
for(int i=0;i<=n-1;i+=2)
{
if(i>=n-2) res=min(res,c[i]);
else res=min(res,c[i]+d[i+3]);
}
printf("%lld\n",res);
memset(c,0,sizeof c);
memset(d,0,sizeof d);
memset(a,0,sizeof a);
}
return 0;
}
后话:b题有思路但是感觉自己做不出来就没有去做,其实仔细想想是能做出来的,思路不是很难,还是在于特殊情况的判定和自己做题时的状态。c题题解的思路很好用前缀和取处理,顺序处理偶数,逆序处理的是奇数。然后从头开始循环判断当前处理,c[i]与d[i+3] 中间是相隔两个所以是d[i+3]。注意:0 long long 表示为 0ll。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!