zoukankan      html  css  js  c++  java
  • Codeforces Round #661 (Div. 3) D. Binary String To Subsequences

    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⋅(10^4)) — the number of test cases. Then t test cases follow.

    The first line of the test case contains one integer n (1≤n≤2⋅(10^5)) — 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⋅(10^5)(∑n≤2⋅(10^5) ).

    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.

    Example

    Input

    Copy

    4
    4
    0011
    6
    111111
    5
    10101
    8
    01010000
    

    Output

    Copy

    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 
    

    开两个栈,一个栈a存放当前末尾为0的子序列的编号,另一个栈b存放当前末尾为1的子序列的编号,初始都为空。然后遍历字符串,如果遇到0的话,首先判断b是否为空,是的话++tot(tot为当前子序列的个数,说明新开了一个序列),把tot赋给当前数,然后把自增后的tot push进a;如果b不空,则把b的栈顶的数移除并push进a中(意味着把当前的0放到b栈顶的序列后面,这样b由末尾为0变为末尾为1),同时把这个编号赋给当前位置。最后输出两个栈size的和以及各个位置的序列编号即可。

    #include <bits/stdc++.h>
    using namespace std;
    int ans[200005] = {0};
    int main()
    {
    	int t;
    	cin >> t;
    	while(t--)
    	{
    		string s;
    		int n;
    		cin >> n;
    		cin >> s;
    		stack<int> a, b;//a存末尾为0的子列的编号 b存为1的子列的编号 
    		int tot = 0;//总共拆分出来的子列 
    		for(int i = 0; i < s.size(); i++)
    		{
    			if(s[i] == '0')
    			{
    				if(b.size())
    				{
    					ans[i] = b.top();
    					int temp = b.top();
    					b.pop();
    					a.push(temp);
    				}
    				else
    				{
    					tot++;
    					ans[i] = tot;
    					a.push(tot);
    				}
    			}
    			else
    			{
    				if(a.size())
    				{
    					ans[i] = a.top();
    					int temp = a.top();
    					a.pop();
    					b.push(temp);
    				}
    				else
    				{
    					tot++;
    					ans[i] = tot;
    					b.push(tot);
    				}
    			}
    		} 
    		cout << a.size() + b.size() << endl;
    		for(int i = 0; i < n; i++) cout << ans[i] << ' ';
    		cout << endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    APP热潮来临 图解九种商业模式
    Visual Studio 2010北京发布会
    高薪诚聘项目经理,架构师,高级工程师,工程师,网页设计师
    WCF闲谈:如何在流模式下传递参数
    下周股市走势预测
    明日大盘走势分析
    三步找出牛股技法
    Y COMBINATOR的六大强悍女人转自应用电台
    互联网创业公司失败的7个典型特征应用电台
    更多Windows Phone 8新功能详解
  • 原文地址:https://www.cnblogs.com/lipoicyclic/p/13453155.html
Copyright © 2011-2022 走看看