小蒟蒻一篇杂项总结
t1 bzoj3416 Poi2013 Take-out
原题https://anoxiacxy.github.io/more/bzoj/p/3416.html
题意:小F喜欢玩一个消除游戏——take-out。这是一个单人游戏,游戏者的目标是消除初始时给定的一列砖块,从左往
右标号为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次移除操作移除砖块的位置集合
保证k+1|n,保证输入数据有解
思路:题中说到“中间不能夹着之前消除过的位置”,所以呢倒着想,然后这东西和祖玛蜜汁相似啊,然后呢,像祖玛一样,这东西只要有解,那么肯定有一段是可以消的,之后我们搞个栈+前缀和就ok啦!
#include<stdio.h> #define MAXN 1000002 using namespace std; int n; int sta[MAXN],qsum[MAXN],top; //前缀和的数组,和栈,栈顶 char s[MAXN]; //记录串 int ans[MAXN]; int ask=0; int main() { int i,j,k; scanf("%d%d",&n,&k); scanf("%s",s+1); for(i=1;i<=n;++i) { sta[++top]=i; qsum[top]=qsum[top-1]+(s[i]=='c'); while(top>k&&qsum[top]-qsum[top-k-1]==1) { j=top-k; for(top;top>=j;--top) ans[++ask]=sta[top]; } } for(i=n;i>=1;--i) { printf("%d ",ans[i]); if(i%(k+1)==1)printf("\n"); } return 0; }