原题传送门-Luogu
原题传送门-CF
前置芝士-一点模拟
建议先了解祖玛游戏规则。
题目大意
给定 \(n\) 个数,在其中插入一个数 \(x\),然后不断长度大于 \(3\) 的消除相连的相同的数,问最多能删除多少个。
题目分析
观察到题目的 \(n\) 很小,考虑直接枚举插入位置,然后模拟消除操作,并计算答案。
AC code
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn=105;
int n,k,x;
int a[maxn],b[maxn];
int ansm=-1;//变量,无需多言
int calc()
{
int ret=0;//此次消除个数
for(int i=1;i<=n-1;i++)
{
while(b[i]==-1) i++;
int j=i+1,tar=b[i],cnt=0;//j为末指针,tar为球的颜色,cnt为区间-1个数
while(j<=n+1)
{
if(b[j]==-1)
{
while(b[j]==-1) j++,cnt++;//跨越-1
}
if(b[j]!=tar) break;
j++;
}
j--;
int len=j-i+1-cnt;//计算最终消除长度
if(len<3) continue;//小于3则舍去
ret+=len;
for(int k=i;k<=j;k++)
{
b[k]=-1;//标记为消除
}
}
return ret!=0?ret:-1;//-1表示消除不了了!
}
int work(int pos) //得到插入x后序列
{
for(int i=0;i<=n;i++) b[i]=-1;//用-1表示消除了
int len=n+1;
int i=1,j=1;
while(j<=n+1)
{
if(j==pos)
{
b[j]=x;
}
else
{
b[j]=a[i];
i++;
}
j++;
}//生成b数组,即插入后数组
bool flag=true;
int ans=0;
do{
int x=calc();
if(x==-1) flag=false;
else ans+=x;
}while(flag);//不断消除知道不能消,计算答案
return ans;
}
int main()
{
cin>>n>>k>>x;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n+1;i++)
{
ansm=max(ansm,work(i));
}
cout<<((ansm==0)?0:ansm-1);//输出答案
return 0;
}
一些细节
本题难度不大,但细节较多。
- 移动收尾指针 \(i\) 和 \(j\) 时,一定要处理好加减 \(1\) 的关系。
- 计算长度时,注意区间大小如何计算。
- 关注不能消除以及以及已经被消除的情况,可以使用 \(-1\) 标记。
- 答案数要减 \(1\),无法消除不要输出 \(-1\) 了!
AC记录
希望这篇题解对你有所帮助。
来源链接:https://www.cnblogs.com/vanueber/p/18668479
没有回复内容