Codeforces Round #661 (Div. 3) D. Binary String To Subsequences(思维,字符串)

题目链接

题意:

给你一个01字符串,你能将他分为至少多少个相邻数字不同的子字符串,输出个数和每一个位置的字符属于哪个子串。

思路:

每次记录都从一段连续的0或1开始,a数组记录子串编号,b数组记录编号子串结尾为0还是1,对于每一段连续的0或1,都从编号为1的子串开始遍历,根据b数组判断最后一位的数字看他能否成为该编号子串的最后一位,如果可以就将a[i]变为该编号并改变b数组中该编号子串的结尾数字。

代码:

#include
//#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
const int N=2e5+7;
const int M=2e4+5;
const double eps=1e-8;
const int mod=998244353;
const int inf=0x7fffffff;
const double pi=3.1415926;
using namespace std;
signed main()
{
    IOS;
    int t;
    cin>>t;
    while(t--)
    {
        int n,mx=1,a[N],b[N];
        string s;
        cin>>n;
        cin>>s;
        a[0]=1;
        b[1]=s[0]-'0';
        for(int i=1;i<n;i++)
        {
            if(s[i]==s[i-1])
            {
                a[i]=a[i-1]+1;
                if(a[i]<=mx)
                {
                while(b[a[i]]==s[i]-'0')
                {
                    a[i]++;
                    if(a[i]>mx)
                    {
                        b[a[i]]=s[i]-'0';
                        break;
                    }
                }
                }
                b[a[i]]=s[i]-'0';
                mx=max(mx,a[i]);
            }
            else
            {
                a[i]=1;
            }
        }
        cout<<mx<<endl;
        for(int i=0;i<n;i++)
        {
            cout<<a[i]<<" ";
        }
        cout<<endl;
    }
    return 0;
}

你可能感兴趣的:(思维,字符串)