题意:给你一个01字符串,让你从左到右选出元素进行构造,构造出斑马,元素可以间隔选取,但不能换顺序,然后输出。
思路:构造题,由于我们要构造的序列最终个数不确定,所以开个vector数组储存。
接着for循环扫一遍字符串,遇到0,接在1后面,如果没有另开一行作为新的序列,遇到1接在0后面,如果没有则-1。
关于如何接字符,我们可以看这样一个逻辑:首先第一个字符一定是0,否则判-1。如果出现1,需要接在后面,或者向上一行接。所以需要向下换行一定是连续的0,向上时一定是连续的1,具体看代码。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<string>
#include<map>
#include<vector>
#include<queue>
#include<stack>
#define ll long long
using namespace std;
char s[200020];
vector<ll>v[200020];
ll flag,mmax;
int main()
{
while(~scanf("%s",s+1))
{
ll len=strlen(s+1);
mmax=1;
if(s[1]=='1'||s[len]=='1'){printf("-1\n");continue;} //特判
for(ll i=0;i<=200020;i++)v[i].clear();
ll p=1;
v[1].push_back(1);
flag=0;
for(ll i=2;i<=len;i++)
{
if(s[i]=='0')v[++p].push_back(i); //遇0向下
else
{
if(p==0){flag=1;break;}
v[p--].push_back(i); //遇1先接,在向上
}
mmax=max(p,mmax); //更新真实行数,即序列段数
}
for(ll i=1;i<=mmax;i++) //找一遍有没有1结尾的。有则判-1
{
ll tmp=v[i].size()-1;
if(s[v[i][tmp]]=='1')
{
flag=1;
break;
}
}
if(flag==1)printf("-1\n");
else
{
printf("%lld\n",mmax); //输出结果
for(ll i=1;i<=mmax;i++)
{
ll x=v[i].size();
printf("%lld ",x);
for(ll j=0;j<v[i].size();j++)
{
printf("%lld ",v[i][j]);
}
printf("\n");
}
}
}
return 0;
}