Teams Formation CodeForces - 878B

Teams Formation

题目链接:CodeForces - 878B
题意:给出有n个数的序列, 将该序列重复m次, 如果有k个连续的相同的数, 去掉这k个数, 直到没有连续的相同的k个数为止, 问最后还有几个数?
首先, 我们先把原序列中有的连续的相同的k个数删去,
如果一个序列重复一次, 那么会是他的尾和首相接, 我们需要删去首尾相接后的连续的相同的k个数;
重复m次, 即有m-1次首尾相接;
注意用long long;

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
const int maxn = 1e5+10;
pair<long long, long long> sp[maxn];
long long a[maxn];
long long rec, rec1, ans, l, r;
int main(){
	int n, m, k, top=0;
	scanf("%d%d%d", &n, &k, &m);
	for(long long i=0; i<n; i++) scanf("%lld", &a[i]);
	for(long long i=0; i<n; i++){//删掉原序列中连续的相同的k个数
		if(!top||sp[top].first!=a[i]) sp[++top]=make_pair(a[i], 1);
		else sp[top].second = (sp[top].second+1)%k;
		if(sp[top].second==0) top--;
	}
	rec=rec1=ans=0;
	l=1, r=top;
	for(long long i=1; i<=top; i++) rec+=sp[i].second;//rec为原序列还剩多少数
	while(l<r && sp[l].first==sp[r].first && (sp[l].second+sp[r].second)%k==0)//计算首尾相接时应删去的数的个数
		rec1+=sp[l].second+sp[r].second, l++, r--;
	if(l==r){
		if(sp[l].second*m%k==0)
			ans-=rec1;
		ans+=rec*m-rec1*(m-1)-sp[l].second*m/k*k;
	}
	else{
		if(sp[l].first==sp[r].first)
			rec1+=(sp[l].second+sp[r].second)/k*k;
		ans=rec*m-rec1*(m-1);
	}
	printf("%lld\n", ans);
	return 0;
}


猜你喜欢

转载自blog.csdn.net/sirius_han/article/details/80082215