题目链接:
CodeForces 950C
题意:
给出一串数字,输出可以构成的斑马数的情况,其中斑马数是像0 010这样的,开始和结尾是0并且01是相间出现的,输出数据有多组(第一行输出组数),每组的第一个数是这个斑马数的长度,后面的n个数字是斑马数的下标。并且要保证每个数字都输出,不然就不成立,输出-1.
题解:
以一个串为例:
给定字符串01001100(如下):
1、
2、
3、
4、
5、
6、
下面还有两个图,就不给了,直接就是让0补到最左边的1下面,还有第二列的1下面。
也就是说,我们只需要维护一个数组就行了,保证这个数组的序列满足满足斑马数的要求!
就拿上面的几个图举例子吧,这个序列是01001100,那么一开始的0,放到第一列,然后输入一个1,把1放到0的下面,(那么我们在维护这个数组的时候应该确定如果遇到0应该是++num,如果遇到1的时候应该是num--,也就是说我们维护数组的时候num前面的都是以0结尾的)!
由于我们在维护这个数组的时候不知道现在有多少组数据,那么我们就可以使用vector容器来存储数据的下标,这样最后输出的时候也会十分的方便。
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<string.h>
#include<iostream>
#include<map>
#include<cmath>
#include<string>
using namespace std;
const int maxn=200000+10;
char a[maxn];
int cnt,maxx,num;
vector<int>mpp[maxn];
int main()
{
scanf("%s",a+1);//从下标为1开始读入数据
int l1=strlen(a+1);//计算字符串长度
for(int i=1; i<=l1; ++i)
{
if(a[i]=='0')
{
mpp[++num].push_back(i);//如果是0的话,就往右移动一列,这里说明前面的最后一位都是0
}
else
{
if(num==0)
{
printf("-1\n");//如果出现了1并且前面没有0的话,这个数就不是斑马数
return 0;
}
mpp[num--].push_back(i);//反之存在为0的情况,那么我们就把列数往前推一位
}
maxx=max(maxx,num);//这里记录列数
}
if(maxx!=num)
printf("-1\n");//如果不相等代表有没有出现010或者0的情况
else
{
printf("%d\n",maxx);
for(int i=1; i<=maxx; ++i)
{
printf("%d",mpp[i].size());
for(int j=0; j<mpp[i].size(); ++j)
{
printf(" %d",mpp[i][j]);
}
printf("\n");
}
}
return 0;
}