zoukankan      html  css  js  c++  java
  • 模拟 [D. Colorful Points ]

    模拟 D. Colorful Points

    题目大意:

    给你一个字符串,对于一个字符,如果左右两边的字符和这个不一样,那么就删除这个字符,一次可以删去多个字符,问最少的删除次数,使得不能再删。

    题解:

    这个是一个模拟题,写起来感觉挺恶心的,但是也很考验写题的技巧,用好的技巧写就显得很简洁。

    按照网上的一个思路写的,首先证明一下这个解题思路:

    假设有k个不同的块(每一块都是相同的),那么每次删除 (2*(k-1)) 个数,所以一共遍历 (frac{n}{2*(k-1)}) ,每次遍历的复杂度是 (O(k)) ,所以总的复杂度是 (k*frac{n}{2*(k-1)})

    写法:

    因为最后的形式是 (aaaabbbccababa) ,那么可以等价于 ([4a,3b,2c,1a,1b,1a,1b,1a])

    然后很容易发现,每次操作如果是左右两边的块就 (-1) ,如果是中间的块就 (-2) ,所以每次操作完之后就可以重新合并一次,因为有些块删除之后,两边的块可以连在一起。

    这个合并函数可以记录学习一下,以后碰到类似的可以使用这种方法:

    void cal(){
    	int len = n;
    	n = 0;
    	for(int i=1;i<=len;i++){
    		if(e[i].num>0){
    			if(e[i].val==e[n].val) e[n].num += e[i].num;
    			else e[++n]=e[i];
    		}
    	}
    }
    

    (CODE:)

    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    #define debug(x) cout<<"debug:"<<#x<<" = "<<x<<endl;
    using namespace std;
    typedef long long ll;
    const int maxn = 1e6+10;
    struct node{
    	int val,num;
    	node(int val=0,int num=0):val(val),num(num){}
    }e[maxn];
    char s[maxn];
    int n;
    void cal(){
    	int len = n;
    	n = 0;
    	for(int i=1;i<=len;i++){
    		if(e[i].num>0){
    			if(e[i].val==e[n].val) e[n].num += e[i].num;
    			else e[++n]=e[i];
    		}
    	}
    }
    
    void solve(){
    	int ans = 0;
    	while(n>1){
    		for(int i=2;i<n;i++) e[i].num -=2;
    		e[1].num--,e[n].num--;
    		ans++;
    		cal();
    	}
    	printf("%d
    ", ans);
    }
    int main(){
    	scanf("%s",s+1);
    	n = strlen(s+1);
    	e[0].val = -1;
    	for(int i=1;i<=n;i++) e[i].val = s[i]-'a',e[i].num = 1;
    	cal();
    	solve();
    	return 0;
    }
    
  • 相关阅读:
    January 25th, 2018 Week 04th Thursday
    January 24th, 2018 Week 04th Wednesday
    January 23rd, 2018 Week 04th Tuesday
    January 22nd, 2018 Week 04th Monday
    January 21st, 2018 Week 3rd Sunday
    January 20th, 2018 Week 3rd Saturday
    January 19th, 2018 Week 3rd Friday
    January 18th, 2018 Week 03rd Thursday
    January 17th, 2018 Week 03rd Wednesday
    January 16th, 2018 Week 03rd Tuesday
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/13490849.html
Copyright © 2011-2022 走看看