2022 Shanghai Collegiate Programming Contest(模拟+贪心)

Problem - H - CodeforcesProblem - H - Codeforces

 

 题意:有一个由n个数组成的环,每个位置需要被涂成对应颜色,然后有一个方便的机器,这个机器可以涂连续个子区间  k,然后新涂成的颜色会覆盖之前涂成的颜色,问你需要能够涂正确的次数的最小数目,如果不能输出-1。

思路:首先因为是一个环状,所以我们可以扩大一下形成2*n数组,然后每次选区域只选n个区域所为环处理。然后对应这个题目,如果k是1的话那么无论怎么涂结果都是一样的,然后因为这个机器一定会涂k个区域,那么如果所有连续区间的长度小于k的区间那么一定是不能满足条件的,然后只要存在连续区间大于等于k,那么无论怎么涂都可以最后那个子区间重新覆盖得到。

那么可以处理环把长度超过k的子序列区间放到环的末尾,先处理环的头部,然后每次根据要涂的长度增加相应的sum,最后直接输出就可以了。

/**
 *  ┏┓   ┏┓+ +
 * ┏┛┻━━━┛┻┓ + +
 * ┃       ┃
 * ┃   ━   ┃ ++ + + +
 *  ████━████+
 *  ◥██◤ ◥██◤ +
 * ┃   ┻   ┃
 * ┃       ┃ + +
 * ┗━┓   ┏━┛
 *   ┃   ┃ + + + +Code is far away from  
 *   ┃   ┃ + bug with the animal protecting
 *   ┃    ┗━━━┓ 神兽保佑,代码无bug 
 *   ┃  	    ┣┓
 *    ┃        ┏┛
 *     ┗┓┓┏━┳┓┏┛ + + + +
 *    ┃┫┫ ┃┫┫
 *    ┗┻┛ ┗┻┛+ + + +
 */

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
#include <math.h>
#include <vector>
#include <queue>
#include <map>
#define ll long long
using namespace std;

const int N = 3000000 + 100;
int n, m, h;
ll s[N];

int main()
{
	int t;
	cin >> t;
	while (t--)
	{

		scanf("%d%d%d", &n, &m, &h);
		for (int i = 1; i <= n; i++)
		{
			scanf("%lld", &s[i]);
			s[i + n] = s[i];
		}
		int flag = 0;
		if (h == 1)
		{
			printf("%d\n", n);
			continue;
		}
		int ii = n;
		for (int i = 1; i <= 2 * n; i++) //寻找长度大于等于k的子序列位置
		{
			int j = i, time = 0;
			while (s[i] == s[j])
			{
				j++;
				time++;
			}
			i = j - 1;
			if (time >= h)
			{
				flag = 1;
				ii = j - 1;
				break;
			}
		}

		if (!flag)
		{
			printf("-1\n");
			continue;
		}

		if (ii < n)//因为遍历是要从ii的前n个数开始遍历,所有如果ii<n要先+i保证前面有数
			ii += n;
		ll sum = 0;

		for (int i = ii - n + 1; i < ii; i++)//直接模拟
		{
			if (s[i] == s[i + 1])
			{
				int k = 2;
				int j = i + 2;
				while (s[i] == s[j])
				{
					j++;
					k++;
				}
				i = j - 1;
				sum += (k + (h - 1)) / h;
				// if(j>=n&&k<h)sum++;
			}
			else sum++;
		}
		printf("%lld\n", sum);
	}
	return 0;
}

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值