題意:給你一個只由0和1組成的字符串,求能分成多少個由0開頭0結尾並且中間01交替排列的子序列。這裏題意需要注意的是,如果原字符串中由1開頭或由1結尾是不合法的,如果有兩個1挨着也是不合法的。
題解:由於要求輸出的是每個子序列的長度以及其中數字在原字符串的位置,所以可以考慮用vector的二維數組儲存分成的每個序列的元素的下標,每個一維的大小就是序列的長度。要分成的序列一定是0開頭0結尾並且01交替的序列或者是隻有0組成的,所以我們從左開始遍歷,遇到0就存進新的容器,遇到1就存進上一個0存進的位置,並且由於每個1後面還需要一個0,所以存進1的時候我們要把標記數組下標的變量減1,使下一個出現的0存進當前這個1所在的容器。最後遍歷輸出就行了。
附上代碼:
#include<bits/stdc++.h>
using namespace std;
int n,m;
const int maxn=200010;
char s[maxn];
vector<int>q[maxn];
int main()
{
scanf("%s",s); //從1開始方便記錄
int len=strlen(s);
int cnt=0,num=0;
for(int i=0; i<len; i++)
{
if(s[i]=='0')
q[++num].push_back(i+1);//遇到0就放到一個新的容器裏面
else
{
if(num==0) //前面沒有0的子序列
{
printf("-1\n");
return 0;
}
q[num--].push_back(i+1); //出現了1就把它放在上一個0的容器裏面
//並且編號要減1使下一個0也存進這個1的容器
}
cnt=max(cnt,num);
}
if(cnt!=num) //最後的不是0
{
printf("-1\n");
return 0;
}
printf("%d\n",cnt);
for(int i=1; i<=cnt; i++)
{
printf("%d ",q[i].size());
for(int j=0; j<q[i].size(); j++)
printf("%d ",q[i][j]);
printf("\n");
}
return 0;
}