題目描述:
鏈接:https://ac.nowcoder.com/acm/contest/3402/D
來源:牛客網
米多立亞少年此時正在學習one for all全覆蓋5%,但是他不想努力了,於是哆啦A夢拿出神奇道具幫助米多立亞少年,讓他可以1分鐘學會全覆蓋。當米多立亞少年使用這個道具的時候,道具的屏幕上會出現一個字符串(只由’0’ , ‘1’ , ‘2’ 三種字符構成) 。
這些字符串有如下的交換規則:對於相鄰的兩個字符,‘01’可以變成’10’ , ‘10’可以變成’01’ , ‘12’可以變成’21’ , ‘21’可以變成’12’,可以交換無數次。
米多立亞少年需要儘快反饋給道具一個最小字典序的字符串,你可以幫助他嗎?
輸入描述:
多組測試用例,保證 ∑|s|≤ 5*107;
每組測試用例一行,表示道具屏幕上出現的只包含‘0’,‘1’,‘2’的字符串s,(0<|s| ≤ 106,|s|爲字符串s的長度)
輸出描述:
輸出交換後的最小字典序的字符串
輸入樣例:
101022
01010120
0121021
輸出樣例:
001122
00011120
0111202
核心思想:
0和2的相對位置固定,1位置隨便擺放。要使字典序最小,將全部的1挪到第一個2之前即可。
代碼如下:
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=1e6+20;
char s[N];
int main()
{
while(~scanf("%s",s))
{
int len=strlen(s),cnt=0,p=len;//cnt記錄1的個數,p爲第一個2的位置
//得到cnt和p
for(int i=len-1;i>=0;i--)
if(s[i]=='1')
cnt++;
else if(s[i]=='2')
p=i;
//輸出p之前的0
for(int i=0;i<p;i++)
if(s[i]=='0')
printf("0");
//在第一個2之前輸出全部的1
for(int i=0;i<cnt;i++)
printf("1");
//輸出後續非1字符
for(int i=p;i<len;i++)
if(s[i]!='1')
printf("%c",s[i]);
printf("\n");
}
return 0;
}