题目大意
有一行砖块,一些是黑的,一些是白的,每一次可以选择$k$个白的砖块与$1$个黑的砖块挪走,但任意两个选的砖块之间不能有已经挪走的砖块,构造方案。
题目分析
将白色砖块看做$1$,黑色砖块看做$-k$。
那么当栈顶的$k+1$个元素和为$0$的时候就可以一起弹出。
倒序输出就可以保证题目的限制。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| #include<algorithm> #include<iostream> #include<iomanip> #include<cstring> #include<cstdlib> #include<climits> #include<vector> #include<cstdio> #include<cmath> #include<queue> using namespace std;
inline const int Get_Int() { int num=0,bj=1; char x=getchar(); while(x<'0'||x>'9') { if(x=='-')bj=-1; x=getchar(); } while(x>='0'&&x<='9') { num=num*10+x-'0'; x=getchar(); } return num*bj; }
const int maxn=1000005;
int n,k,top=0,a[maxn],sum[maxn]; vector<vector<int> >ans;
int main() { n=Get_Int(); k=Get_Int(); for(int i=1; i<=n; i++) { char ch; scanf("%c",&ch); int x=ch=='c'?-k:1; a[++top]=i; sum[top]=sum[top-1]+x; while(top>=k+1&&sum[top]-sum[top-k-1]==0) { vector<int> tmp; for(int j=1; j<=k+1; j++)tmp.push_back(a[top--]); reverse(tmp.begin(),tmp.end()); ans.push_back(tmp); } } reverse(ans.begin(),ans.end()); for(auto x:ans) { for(int j=0; j<k+1; j++)printf("%d ",x[j]); putchar('\n'); } return 0; }
|