为了能到远方,脚下的每一步都不能少.|

vanueber

园龄:2年6个月粉丝:0关注:2

CF430B 解题报告

原题传送门-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;
}

一些细节

本题难度不大,但细节较多。

  • 移动收尾指针 ij 时,一定要处理好加减 1 的关系。
  • 计算长度时,注意区间大小如何计算。
  • 关注不能消除以及以及已经被消除的情况,可以使用 1 标记。
  • 答案数要减 1,无法消除不要输出 1 了!

AC记录

希望这篇题解对你有所帮助。

本文作者:vanueber

本文链接:https://www.cnblogs.com/vanueber/p/18668479

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   vanueber  阅读(2)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起