题目链接:http://codeforces.com/contest/950
flag:思维题+模拟
例子:00110110111000
①前面的两个0形成了:
序列1:{0}
序列2:{0}
均是合法的序列;
②第3个字符‘1’,是不可能单独成一个序列的首元素,不符要求;必须放进现合法序列中,放进序列1中:
序列1:{0,1}
序列2:{0}
③第4个字符‘1’,同三一样,必须放进合法序列中,于是放进序列2中:
序列1:{0,1}
序列2:{0,1}
④第5个字符‘0’,可以开一个合法序列,但是将一个不合法序列变为合法序列的价值好些!放进序列2中:
序列1:{0,1}
序列2:{0,1,0}
⑤第6个字符‘1’,同理②,放入序列2中,2个序列又成了不合法的!
序列1:{0,1}
序列2:{0,1,0,1}
⑥第7个字符‘1’,同理②,但此时已经没有合法序列了,所以无法拆成!
* i记录前i个Vector是以1结尾的串(不合法序列);j记录当前开的Vector的个数;
后面来一个‘1’,这个必须放在‘0’的后面,所以放在后面i+1~j个Vector其中一个,不妨放在第i+1个Vector中,
使得不合法序列多了一个!如果这时候i==j,就表示此时已经没有‘0’可以接了,所以失败!无法分解!成功即++i!
后面来一个 ‘0’,最佳放法是 将第i个Vector变为合法的方法,即i>0时,放入第i个Vector中,--i; 如果i==0,表
示现在前j个Vector全是合法的序列,我们于是开第j+1个Vector合法序列,++j!
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <vector>
#include <math.h>
#define Maxn 201000
using namespace std;
char s[Maxn];
vector<int> Q[Maxn];
int main(){
scanf("%s",s);
int str=strlen(s);
int i=0,j=0;
int flag=1;
for(int k=0;k<str;++k){
if(s[k]=='1'){
++i;
if(i>j){flag=0;break;}
Q[i].push_back(k+1);
}else{
if(i>0){
--i;
Q[i+1].push_back(k+1);
}else {
Q[++j].push_back(k+1);
}
}
}
if(i>0){flag=0;}
if(flag==0)printf("-1\n");
else {
printf("%d\n",j);
for(int k=1;k<=j;++k){
printf("%d",Q[k].size());
for(int v=0;v<Q[k].size();++v){
printf(" %d",Q[k][v]);
}
printf("\n");
}
}
return 0;
}