Balanced Ternary String CodeForces - 1102D (贪心+思维)

You are given a string ss consisting of exactly nn characters, and each character is either ‘0‘, ‘1‘ or ‘2‘. Such strings are called ternary strings.

Your task is to replace minimum number of characters in this string with other characters to obtain a balanced ternary string (balanced ternary string is a ternary string such that the number of characters ‘0‘ in this string is equal to the number of characters ‘1‘, and the number of characters ‘1‘ (and ‘0‘ obviously) is equal to the number of characters ‘2‘).

Among all possible balanced ternary strings you have to obtain the lexicographically (alphabetically) smallest.

Note that you can neither remove characters from the string nor add characters to the string. Also note that you can replace the given characters only with characters ‘0‘, ‘1‘ and ‘2‘.

It is guaranteed that the answer exists.

Input

The first line of the input contains one integer nn (3≤n≤3⋅1053≤n≤3⋅105, nn is divisible by 33) — the number of characters in ss.

The second line contains the string ss consisting of exactly nn characters ‘0‘, ‘1‘ and ‘2‘.

Output

Print one string — the lexicographically (alphabetically) smallest balanced ternary string which can be obtained from the given one with minimum number of replacements.

Because nn is divisible by 33 it is obvious that the answer exists. And it is obvious that there is only one possible answer.

Examples

Input

3
121

Output

021

Input

6
000000

Output

001122

Input

6
211200

Output

211200

Input

6
120110

Outpu1201

题目链接 :https://vjudge.net/problem/CodeForces-1102D题意:给你一个长度为N个字符串,N是3的倍数,字符串中只包括‘0‘,‘1‘,‘2‘这三个字符,题目让你修改最少数量的字符,使这个字符串的中的这三个字符的数量相等,即如果N=6,需要含有两个‘1’,两个‘2’,两个‘0’,并且希望你输出满足条件并且字典序最小的那一个。

思路:贪心构造。先预处理一下每一个字符出现了多少次,然后遍历一下字符串,当0字符出现了大于n/3的时候,把‘0‘最后一个出现的位置尝试改成‘2’,如果‘2’的数量不小于n/3,那么就改成‘1‘。之所以这个顺序,就是因为要求字典序最小,这样构造出来的最小。‘1’,’2’类推该怎么构造。既然我们每一次可能用到某一个字符第一次出现的位置或者最后一个出现的位置,我们就要开一个双端队列,然后预处理的时候把这个信息就加入到对应的双端中,注意:这里讲的最后一次出现的,是对于刚预处理完的,如果每一次把他的最后一个出现的给改成别的字符了,那么就要从双端中弹出,次后的继位。

细节可以看代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), ‘\0‘, sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define gg(x) getInt(&x)
using namespace std;
typedef long long ll;
inline void getInt(int* p);
const int maxn=1000010;
const int inf=0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
int n;
char s[maxn];
char ans[maxn];
int cnt[55];
int num[11];
deque<int> v[5];
int main()
{
    gbtb;
    cin>>n;
    cin>>s;
    strcpy(ans,s);
    repd(i,0,n-1)
    {
        if(s[i]==‘0‘)
        {
            cnt[0]++;
            v[0].pb(i);
        }else if(s[i]==‘1‘)
        {
            cnt[1]++;
            v[1].pb(i);
        }else
        {
            v[2].pb(i);
            cnt[2]++;
        }
    }
    int x=n/3;
//    for(int i=n-1;i>=0;i--)
//    {
//        if(s[i]==‘0‘)
//        {
//            if(cnt[0]>x)
//            {
//                if(cnt[2]<x)
//                {
//                    s[i]=‘2‘;
//                    cnt[2]++;
//
//                }else
//                {
//                    s[i]=‘1‘;
//                    cnt[1]++;
//                }
//                cnt[0]--;
//            }
//        }
//    }
    repd(i,0,n-1)
    {
        if(s[i]==‘0‘)
        {
            if(cnt[0]>x)
            {
                int index=v[0].back();
                v[0].pop_back();
//                *(--v[0].end());
//                v[0].erase(--v[0].end());
                if(cnt[2]<x)
                {
                    ans[index]=‘2‘;
                    cnt[2]++;

                }else
                {
                    ans[index]=‘1‘;
                    cnt[1]++;
                }
                cnt[0]--;
            }
        }
        else if(s[i]==‘1‘)
        {
            if(cnt[1]>x)
            {
                if(cnt[2]<x)
                {
                    int index=v[1].back();
                        v[1].pop_back();
                    ans[index]=‘2‘;
                    cnt[2]++;

                }else
                {
                    int index=v[1].front();
                    v[1].pop_front();
                    ans[index]=‘0‘;
                    cnt[0]++;
                }
                cnt[1]--;
            }
        }else
        {
            if(cnt[2]>x)
            {
                int index=v[2].front();
                    v[2].pop_front();
                if(cnt[0]<x)
                {

                    ans[index]=‘0‘;
                    cnt[0]++;

                }else
                {
                    ans[index]=‘1‘;
                    cnt[1]++;
                }
                cnt[2]--;
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}

inline void getInt(int* p) {
    char ch;
    do {
        ch = getchar();
    } while (ch == ‘ ‘ || ch == ‘\n‘);
    if (ch == ‘-‘) {
        *p = -(getchar() - ‘0‘);
        while ((ch = getchar()) >= ‘0‘ && ch <= ‘9‘) {
            *p = *p * 10 - ch + ‘0‘;
        }
    }
    else {
        *p = ch - ‘0‘;
        while ((ch = getchar()) >= ‘0‘ && ch <= ‘9‘) {
            *p = *p * 10 + ch - ‘0‘;
        }
    }
}



原文地址:https://www.cnblogs.com/qieqiemin/p/10253246.html

时间: 2024-10-13 08:30:39

Balanced Ternary String CodeForces - 1102D (贪心+思维)的相关文章

贪心/思维题 Codeforces Round #310 (Div. 2) C. Case of Matryoshkas

题目传送门 1 /* 2 题意:套娃娃,可以套一个单独的娃娃,或者把最后面的娃娃取出,最后使得0-1-2-...-(n-1),问最少要几步 3 贪心/思维题:娃娃的状态:取出+套上(2),套上(1), 已套上(0),先从1开始找到已经套好的娃娃层数, 4 其他是2次操作,还要减去k-1个娃娃是只要套上就可以 5 详细解释:http://blog.csdn.net/firstlucker/article/details/46671251 6 */ 7 #include <cstdio> 8 #i

Codeforces Round #546 (Div. 2) D 贪心 + 思维

https://codeforces.com/contest/1136/problem/D 贪心 + 思维 题意 你面前有一个队列,加上你有n个人(n<=3e5),有m(m<=个交换法则,假如u在v相邻前面,那么u和v可以交换位置,问你是队列最后一个人的时候你最前可以换到前面哪里 题解 因为相邻才能换,所以最后一个换到前面一定是一步一步向前走,所以不存在还要向后走的情况 设最后一个为u,假设前面有一个能和u换位置的集合,那么需要将这些点尽量往后移动去接u 假设前面有一个不能和u换位置的集合S,

codeforce 985C Liebig&#39;s Barrels(贪心+思维)

Liebig's Barrels time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output You have m?=?n·k wooden staves. The i-th stave has length ai. You have to assemble n barrels consisting of k staves each, y

hdu 4898 LCP+贪心思维

题意:将一个字符串切成k块,使得字典序最大的那块最小. ORZ  WJMZBMR,几行题解读了一天才懂. 快速比较两个子串的大小可以利用LCP(最长公共前缀),比较公共前缀的下一个字符的大小就够了. 利用这种思想,首先我们可以预处理所有子串的LCP(后缀数组+记录 O(2nlog(2n))+O(n*n),dp(O(4*n*n))) 然后将这些子串利用LCP按照字典序排序,开始二分答案. 二分的答案就是这K个块字典序的上限.假设以i作为起点,由于字典序上限已知,所以我们可以立刻求出i点最远能选到哪

Codeforces 437D 贪心+并查集

这个题目让我想起了上次在湘潭赛的那道跪死了的题.也是最值问题,这个也是,有n个动物园 每个都有权值 然后被m条路径相连接,保证图是连通的,然后求所有的p[i][j]之和.i,j为任意两个zoo,pij就为i到j路上遇到的包括i j在内的最小权值的zoo 然后我就焦头烂额了一下,这个明显就是看某个最小值为最后的结果发挥了多少次作用,但这个是图,要知道某个节点到底给多少条路径贡献出了最小值,还真是有点没头绪(在已知的复杂度一看 最多只能用nlogn的),最后是看了解答才知道的 用并查集来解决某个最小

UVA - 10559 Blocks 和 Vasya and Binary String CodeForces - 1107E (dp OR 记忆化搜索)

UVA - 10559 Blocks 题意:消消乐,每次连续相同的可以消除,分数加上长度的平方,问最多可以获得几分全部消完 题解: 区间dp + 记忆化搜索 dp[i][j][k] : (区间 [i,  j] 后面带上一段和 j 颜色相同的且长度为 k )的消消乐最大积分 1.消最后一段颜色和 j 颜色相同的 dp[i][j][k] <-- dp[i][j-1][0] + (k+1)^2 2.对于i <= l < j, 如果 l 和 j 的颜色相同, 那么可以把 [l+1, j-1]消掉

[CF1009B]Minimum Ternary String(思维)

题目链接 http://codeforces.com/problemset/problem/1009/B 题意 给一个只含0.1.2串,只能做相邻的01交换或者相邻的12交换操作,问经过数次操作(可以是0次)能得到的最小字典序的串是什么. 题解 思维题 关键是把题意理解为:固定0.2的相对位置,往里随意放1,能得到的最小字典序. 显然,目标是把所有1放到0后1前好,故放到第一个2222前,若没有2则放到字符串最前. 关于存储串的形式,存到数组记1的数目即可,然后打印做处理即可. 代码 impor

codeforces 893D Credit Card 贪心 思维

codeforces 893D Credit Card 题目大意: 有一张信用卡可以使用,每天白天都可以去给卡充钱.到了晚上,进入银行对卡的操作时间,操作有三种: 1.\(a_i>0\) 银行会给卡充入\(a_i\)元 2.\(a_i<0\) 银行从卡中扣除\(a_i\)元 3.\(a_i=0\) 银行对你的卡进行评估,违背了规则就无权再使用此卡 规则1:卡内的余额不得超过\(d\)元 规则2:当\(a_i=0\)时,卡内的余额不能是负数 现在问为了维持信用的平衡,最少去银行几次.(去一次,充

Diagonal Walking v.2 CodeForces - 1036B (思维,贪心)

Diagonal Walking v.2 CodeForces - 1036B Mikhail walks on a Cartesian plane. He starts at the point (0,0)(0,0), and in one move he can go to any of eight adjacent points. For example, if Mikhail is currently at the point (0,0)(0,0), he can go to any o