Codeforces Round #661 (Div. 3)D. Binary String To Subsequences【vector】

参考大佬的博客,写的很好https://blog.csdn.net/qq_43765333/article/details/107861858?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160292028519724848333971%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=160292028519724848333971&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~rank_v28-1-107861858.first_rank_ecpm_v3_pc_rank_v2&utm_term=+Binary+String+To+Subsequences&spm=1018.2118.3001.4187

题目

传送门
You are given a binary string s consisting of n zeros and ones.

Your task is to divide the given string into the minimum number of subsequences in such a way that each character of the string belongs to exactly one subsequence and each subsequence looks like “010101 …” or “101010 …” (i.e. the subsequence should not contain two adjacent zeros or ones).

Recall that a subsequence is a sequence that can be derived from the given sequence by deleting zero or more elements without changing the order of the remaining elements. For example, subsequences of “1011101” are “0”, “1”, “11111”, “0111”, “101”, “1001”, but not “000”, “101010” and “11100”.

You have to answer t independent test cases.

Input
The first line of the input contains one integer t (1≤t≤2⋅104) — the number of test cases. Then t test cases follow.

The first line of the test case contains one integer n (1≤n≤2⋅105) — the length of s. The second line of the test case contains n characters ‘0’ and ‘1’ — the string s.

It is guaranteed that the sum of n does not exceed 2⋅105 (∑n≤2⋅105).

Output
For each test case, print the answer: in the first line print one integer k (1≤k≤n) — the minimum number of subsequences you can divide the string s to. In the second line print n integers a1,a2,…,an (1≤ai≤k), where ai is the number of subsequence the i-th character of s belongs to.

If there are several answers, you can print any.

输入
4
4
0011
6
111111
5
10101
8
01010000
输出
2
1 2 2 1
6
1 2 3 4 5 6
1
1 1 1 1 1
4
1 1 1 1 1 2 3 4

题意,t组样例,每次给你一个由0,1组合而成的串,和他的长度n,问这个串最少可以分成几个类型为010101…或101010…的子序列(可以不连续)

思路,求最少可以分成几个010101…或101010…的子序列,就是求最少可以匹配几个子序列,我们可以开一个vector数组vec,vec【0】表示需要匹配0的子序列,vec【1】表示需要匹配1的子序列,当a[i]=='0’时我们当然要去找需要匹配0的子序列vec【0】,我们看他是否为空,为空的话我们需要新增一个序列并把当前序列的标号放在vec【1】,否则我们直接把vec【0】中最后一个序列标号拿出来放在vec【1】表示此序列末尾为零需要匹配1;当a[i]='1’时同理,具体看代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<sstream>
#include<queue>
#include<stack>
#include<vector>
using namespace std;
char a[210000];
int b[210000];
vector<int>vec[2];
  solve()
  {
      memset(a,0,sizeof(a));
    int n;
    cin>>n>>a;
    vec[0].clear();
    vec[1].clear();
    memset(b,0,sizeof(b));
    int idx=1,sum=0;//idx表示目前的子序列的数量
    for(int i=0;i<n;i++)
       {
        if(a[i]=='0')
    {
        if(!vec[0].size())
          {
              b[i]=idx;//b[i]表示第i个元素所在的序列
              vec[1].push_back(idx);//把当前的序列标号放入
              idx++;//子序列数量增加
          }
            else
            {
                b[i]=vec[0].back();//从需要匹配零的序列中拿出最后一个
                vec[0].pop_back();
                vec[1].push_back(b[i]);//a[i]==0,末尾加上零后需要匹配1,放入vec【1】
            }

    }
      else
      {
          if(!vec[1].size())
          {
              b[i]=idx;
              vec[0].push_back(idx);
              idx++;
          }
            else
            {
                b[i]=vec[1].back();
                vec[1].pop_back();
                vec[0].push_back(b[i]);
            }
      }
      sum=max(sum,b[i]);}
      printf("%d\n",sum);
      for(int i=0;i<n;i++)
      {printf("%d",b[i]);
        if(i!=n-1)printf(" ");}
        printf("\n");
  }
int main()
{
   int t;
   cin>>t;
   while(t--)
   {
       solve();
   }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值