Codeforces 950 C. Zebras

时间:2023-05-01 09:18:26

http://codeforces.com/contest/950/problem/C

题意:

给出一个01序列,问能否将这个序列分为若干个0开头0结尾的序列

输出方案

如果有解,几个1能在一个序列就在一个序列 一定可以找到解

因为0可以单独1个序列,1必须要依托于0

2个1如果分开 要4个0,连起来要3个0

暴力的做法就是:

如果当前是0,扫一遍已有序列,如果有1结尾的就把这个0放到那个1的后面

没有以1结尾的序列,新建一个序列

如果当前是1,扫一遍已有序列,如果有0结尾的就把这个1放到那个0的后面

没有以0结尾的就无解

极限复杂度是n^2 的

怎么优化?

用vector,cnt记录下一个0要放在哪个vector

如果是0就放在这个cnt所在的vector,cnt++

如果是1那就放到cnt-1所在的vector,先--cnt,再放1

#include<cstdio>
#include<vector>
#include<cstring> using namespace std; #define N 200005 char s[N];
vector<int>V[N]; int main()
{
scanf("%s",s+);
int len=strlen(s+);
if(s[]=='')
{
printf("-1");
return ;
}
int cnt=,tot=;
for(int i=;i<=len;++i)
{
if(s[i]=='') V[cnt++].push_back(i);
else V[--cnt].push_back(i);
if(!cnt && s[i+]=='')
{
printf("-1");
return ;
}
tot=cnt>=tot ? cnt : tot;
}
for(int i=;i<tot;++i)
if(s[V[i][V[i].size()-]]=='')
{
printf("-1");
return ;
}
printf("%d",tot);
int siz;
for(int i=;i<tot;++i)
{
siz=V[i].size();
printf("\n%d",siz);
for(int j=;j<siz;++j) printf(" %d",V[i][j]);
}
return ;
}