Codeforces 950C Zebras 构造

题目链接:Zebras

题意

给定一个 01 字符串,要求找出其中满足下列条件的子序列:

  1. 子序列中 01 相间;
  2. 子序列以 0 开头,以 0 结尾;
  3. 任意两个子序列之间没有交集;
  4. 所有子序列的并为整个序列。

输出找出的子序列方案,子序列的个数不必最少,只要合法即可。

输入

输入只有一行,为一个只包含 0 1 的字符串 s   ( 1 | s | 2 × 10 5 )

输出

第一行输出一个整数 k   ( 1 k | s | ) ,表示子序列的个数,接下去 k 行,每行表示一个子序列,每行第一个整数为 l i   ( 1 l i | s | ) ,表示第 i 个子序列中的字符个数,接下去 l i 个整数每个整数表示序列中的第 j 个元素在原字符串中的下标,下标从 1 开始。如果无法构造出满足条件的序列,输出 1

样例

输入
0010100
输出
3
3 1 3 4
3 2 5 6
1 7
输入
111
输出
-1

题解

将所有 0 字符所在的下标放到一个 s e t 中,所有 1 字符所在的下标放到一个 s e t 中,每次交替从这两个 s e t 中选出大于当前 0 或者 1 的下标的最小值,将这个下标记录到答案中,并从查找的集合中删去,如果某一次查找中,查找到的最后一个数字不是 0 ,则说明 0 的数量不够,需要输出 1 ,如果所有的 01 间隔序列都查找完毕,而存 1 的下标的集合仍为非空,则输出 1 ,其他情况均可以构造出满足条件的 01 间隔序列,最后注意把所有多出来的 0 都单独放到一个序列作为答案。

过题代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <algorithm>
#include <sstream>
using namespace std;

#define LL long long
const int maxn = 200000 + 100;
int len, cnt, Index, num;
bool flag;
vector<int> G[maxn];
set<int> st[2];
set<int>::iterator it;
char str[maxn];

int main() {
    #ifdef LOCAL
    freopen("test.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);
    #endif // LOCAL
    ios::sync_with_stdio(false);

    while(scanf("%s", str + 1) != EOF) {
        cnt = 0;
        flag = true;
        len = strlen(str + 1);
        st[0].clear();
        st[1].clear();
        for(int i = 1; i <= len; ++i) {
            st[str[i] - '0'].insert(i);
        }
        while(!st[0].empty() && !st[1].empty()) {
            Index = 0;
            G[++cnt].clear();
            it = st[0].begin();
            while(it != st[0].end() && it != st[1].end()) {
                num = *it;
                G[cnt].push_back(num);
                st[Index].erase(it);
                Index = 1 - Index;
                it = st[Index].upper_bound(num);
            }
            if(str[G[cnt].back()] == '1') {
                flag = false;
                break;
            }
        }
        if(!st[1].empty() || !flag) {
            printf("-1\n");
            continue;
        }
        while(!st[0].empty()) {
            G[++cnt].clear();
            G[cnt].push_back(*st[0].begin());
            st[0].erase(st[0].begin());
        }
        printf("%d\n", cnt);
        for(int i = 1; i <= cnt; ++i) {
            len = G[i].size();
            printf("%d", len);
            for(int j = 0; j < len; ++j) {
                printf(" %d", G[i][j]);
            }
            printf("\n");
        }
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/CSDNjiangshan/article/details/81388839
今日推荐