zoukankan      html  css  js  c++  java
  • 【BZOJ3416】Poi2013 Take-out 栈

    【BZOJ3416】Poi2013 Take-out

    Description

    小F喜欢玩一个消除游戏——take-out

    保证k+1|n,保证输入数据有解
    这是一个单人游戏 游戏者的目标是消除初始时给定的一列砖块,从左往右标号为1到n,若两个砖块标号相差1,则它们相邻 每一块砖块要么是黑的,要么是白的,这列砖块里面白砖块的数量是黑砖块的数量的k倍 游戏者可以通过执行移除操作来消除砖块 一步移除操作会将k个白砖块和1个黑砖块从序列中移除,而这些被移除的砖块原来所在的位置用透明砖块所代替,其它砖块的位置不变 一个移除操作是合法的当且仅当: 在这次移除中,任意两个被移除的砖块之间,没有透明砖块,且恰好移走k个白砖块和1个黑砖块 显然一个砖块不能被移除两次 小F的智商不够……他对着面前密密麻麻的砖块看傻了眼…… 你能帮他玩通关么?
    Input 第一行两个数:n,k,意义同题目描述 接下来一行一个由'b'和'c'组成的字符串,长度为n,描述这列砖块 第i个砖块如果是黑色的,那么第i个字符为'c' 否则是白色的,第i个字符为'b' (注:波兰文中b是bialy的首字母,c是czarny的首字母)
    Output 输出n/(k+1)行,每行k+1个数,用空格分开,要求递增 第i行表示第i次移除操作移除砖块的位置集合
    HINT 2<=n<=1000000,1<=k<n

    Sample Input

    12 2
    ccbcbbbbbbcb

    Sample Output

    10 11 12
    1 8 9
    2 6 7
    3 4 5

    题解:一开始以为贪心的从两边取,然后模拟即可,直到我被一大坨特判击倒~

    我们将b看成+1,c看成-k,那么每次移除的区间满足左右端点的前缀和相同。所以用栈来维护这个过程,一旦栈顶k+1个元素和=0,则弹栈。最后倒序输出即可。

     

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <vector>
    using namespace std;
    const int maxn=1000010;
    int n,m,k,top;
    vector<int> p[maxn];
    char str[maxn];
    int st[maxn];
    long long s[maxn];
    int main()
    {
    	scanf("%d%d%s",&n,&k,str+1);
    	int i,j;
    	for(i=1;i<=n;i++)
    	{
    		st[++top]=i,s[top]=s[top-1];
    		if(str[i]=='b')	s[top]++;
    		else	s[top]-=k;
    		if(top>=k+1&&s[top-k-1]==s[top])	for(m++,j=0;j<=k;j++)	p[m].push_back(st[top--]);
    	}
    	for(i=m;i>=1;i--)
    	{
    		for(j=k;j>=0;j--)	printf("%d ",p[i][j]);
    		printf("
    ");
    	}
    }

     

     
  • 相关阅读:
    企业老板怎么获得战略视野及组织管理能力?看这些管理书籍就行 了
    公司管理者必读的5本经典书籍推荐
    如何提升自己的领导能力?
    如何培养自己的商业思维能力?
    口才训练书籍推荐
    公司管理课程,我推荐12Reads系列
    比较好的管理学书籍推荐
    如何自学企业管理?你需要看这些书
    DMZ主机实现
    inotify+rsync实现文件即使备份
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7787867.html
Copyright © 2011-2022 走看看