zoukankan      html  css  js  c++  java
  • CodeForces 879D Teams Formation

    题意

    将一个长度为(n)的数组重复(m)遍得到一个长度为(n imes m)的新序列,然后消掉新序列中连续(k)个相同的元素,不断重复这一过程,求最后剩下的序列的长度

    分析

    首先可以明确一件事就是消除的顺序是任意的,最终得到的序列是相同的

    消除的块有两种情况:

    1. 块在序列内部
    2. 块在序列交界处

    首先可以消掉每个序列内部可以消去的块,然后再考虑第二部分
    两个序列首位相接,每遇到(k)个连续的相同颜色的块就消去(注意消去的总长度不超过(n)),最终将一个序列分为左中右三部分

    这样就是前一个序列的右部分和后一个序列的左部分进行消去,(m)个序列进行消去后就变成了:

    左部分+中间部分重复(m)次+右部分

    然后再分成三种情况讨论:

    1. 重复(m)次的中间部分是同一种颜色且是(k)的倍数,那么最终消去了所有元素
    2. 重复(m)次的中间部分是同一种颜色但不能全部消去,那么答案就是消去中间能消的再加上两端
    3. 中间部分有两种颜色或以上说明已经没有可消去的块了
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    using namespace std;
    typedef long long LL;
    typedef pair<int, int> PII;
    #define MP make_pair
    #define PB push_back
    #define REP(i, a, b) for(int i = a; i < b; i++)
    #define PER(i, a, b) for(int i = b - 1; i >= a; i--)
    
    const int maxn = 100000 + 10;
    
    int n, m, k;
    int a[maxn], S[maxn], cnt[maxn], top;
    
    int main() {
    	bool single_color = true;
    	scanf("%d%d%d", &n, &k, &m);
    	REP(i, 0, n) scanf("%d", a + i);
    	REP(i, 1, n) if(a[i] != a[i - 1]) { single_color = false; break; }
    
    	if(single_color) {
    		printf("%I64d
    ", (LL)n * m % k);
    		return 0;
    	}
    
    	REP(i, 0, n) {
    		S[++top] = a[i];
    		if(top > 1 && S[top] == S[top-1]) cnt[top] = cnt[top-1] + 1;
    		else cnt[top] = 1;
    		if(cnt[top] >= k) top -= k;
    	}
    
    	int L = 1, R = top;
    	LL t = 0;
    
    	while(S[L] == S[R] && L < R) {
    		int l = L, r = R, cnt = 0;
    		while(S[l] == S[L] && l < r && cnt < k) { cnt++; l++; }
    		while(S[r] == S[L] && l < r && cnt < k) { cnt++; r--; }
    		if(cnt == k) { L = l; R = r; t += k; }
    		else break;
    	}
    
    	single_color = true;
    	REP(i, L, R) if(S[i] != S[i+1]) { single_color = false; break; }
    	if(single_color) {
    		LL mid = (LL)(R-L+1)*m%k;
    		if(mid) printf("%lld
    ", mid + t);
    		else printf("0
    ");
    	} else {
    		printf("%lld
    ", (LL)(R-L+1)*m + t);
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    Java 书籍 Top 10
    maven学习笔记
    Extjs study
    初学spring mvc
    spring context:componentscan (转)
    What is AspectJ(转)
    java concurrency 学习
    (转)深入浅出REST
    icloud不用翻就能显示地图的办法(转)
    OSGi知识
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/7747876.html
Copyright © 2011-2022 走看看