题目链接:点击打开链接
题解:用vector模拟。遇到0就加到1后面,遇到1就放到0后面,若1没有0可放输出-1。但是会时间超限。n方的时间复杂度过不去。需要优化。分析题意可知每次放数字,只需要知道放在那个正在构造的斑马串后。所以可以用两个队列来记录当前0或1,应该放在那个斑马串后面。网上题解有一种骚操作。但是我没明白啥意思。但是我感觉我得操作最骚 嘿嘿嘿。
具体实现过程看代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
char s[200005];
int a[200005];
vector<int> v[200005]; // 模拟斑马串
queue<int>q; // 存1的位置的队列
queue<int>q0; // 存0的位置的队列
int main(){
for(int i = 0 ; i <= 200005 ; i ++)
v[i].clear();
while(!q.empty()){
q.pop();
}
while(!q0.empty()){
q0.pop();
}
scanf("%s",s);
int len = strlen(s);
if(s[0] == '1' || s[len-1] == '1'){ // 若第一个或最后一个为1,那么必定无法构造。
cout << "-1" << endl;
return 0;
}
for(int i = 0 ; i < len ; i ++)
a[i] = s[i] - '0';
int ans = 1;
v[0].push_back(0);
q0.push(0);
for(int i = 1; i < len ; i ++){
if(a[i] == 0){
if(q.empty()){ // 没有1可放。那么另起一行 ,然后记录0的位置
q0.push(ans);
v[ans ++].push_back(i);
}
else { // 否者就放到1后面,然后记录0的位置 在那个斑马串后面
v[q.front()].push_back(i);
q0.push(q.front());
q.pop();
}
}
else {
if(q0.empty()){ // 若没有0可放 就输出-1
cout << "-1" << endl;
return 0;
}
else { // 若有 就放到0后面,然后记录1的位置在那个斑马串后面
v[q0.front()].push_back(i);
q.push(q0.front());
q0.pop();
}
}
}
for(int i = 0 ; i < ans ; i ++){ // 判断是否都是斑马串
int end = v[i].size();
if(a[v[i][end-1]])
{
cout << -1 << endl;
return 0;
}
}
//cout << " GG" << endl;
printf("%d\n",ans);
int sum = 0 ;
for(int i = 0 ; i < ans ; i ++){
int num = v[i].size();
printf("%d ",num);
for(int j = 0 ; j < num ; j ++){
printf("%d ",v[i][j]+1);
}
cout << endl;
}
}