Codeforces 950 C. Zebras

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+1);
    int len=strlen(s+1);
    if(s[1]=='1')
    {
        printf("-1");
        return 0;
    }
    int cnt=0,tot=0;
    for(int i=1;i<=len;++i)
    {
        if(s[i]=='0') V[cnt++].push_back(i);
        else V[--cnt].push_back(i);
        if(!cnt && s[i+1]=='1')
        {
            printf("-1");
            return 0;
        } 
        tot=cnt>=tot ? cnt : tot;
    }
    for(int i=0;i<tot;++i)
        if(s[V[i][V[i].size()-1]]=='1') 
        {
            printf("-1");
            return 0;
        }
    printf("%d",tot);
    int siz;
    for(int i=0;i<tot;++i)
    {
        siz=V[i].size();
        printf("
%d",siz);
        for(int j=0;j<siz;++j) printf(" %d",V[i][j]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8621929.html