题目链接:http://codeforces.com/problemset/problem/1009/B
题目大意:输入一个数(只含012),我们能够交换0和1以及1和2,但是我们不能交换0和2,我们要经过0次或多次交换得到尽可能小的数(也就是将这串数字尽可能往0 1 2的顺序排)。输出最后的数。
题解:思维题。
考虑到条件,我们可以发现1是可以任意移动的,然后0和2的相对位置是无法改变的。于是我们可以将第一个2出现的位置记录下来,然后将1的数目记录下来,先将第一个2前面的0输出,再将所有的1输出,再从第一个2开始按照2和0的相对位置依次输出2和0,这样得到的就是最优解。
需要注意的就是pos_tow的初始化,我们要将其初始化为len,为什么呢?就是为了防止只有0和1的情况。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <map>
#define P(x) x>0?x:0
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=100005;
char s[maxn];
int pos_two,first_two,sum_one;
int main()
{
while(scanf("%s",s)!=EOF)
{
int len=strlen(s);
pos_two=len;
first_two=0;
sum_one=0;
for(int i=0;i<len;i++)
{
if(s[i]=='2'&&!first_two)
{
first_two=1;
pos_two=i;
}
if(s[i]=='1')
{
sum_one++;
}
}
for(int i=0;i<pos_two;i++)
{
if(s[i]=='0')
{
printf("0");
}
}
while(sum_one--)
printf("1");
for(int i=pos_two;i<len;i++)
{
if(s[i]=='0'||s[i]=='2')
{
printf("%c",s[i]);
}
}
printf("\n");
}
return 0;
}