原理链接: https://codeforces.com/contest/1328/problem/C
测试样例:
Input
4
5
22222
5
21211
1
2
9
220222021
Output
11111
11111
11000
10211
1
1
110111011
110111010
题意: 给定一个长度为3的三进制数为,其中
是由
运算得来的,其中
和
也为三进制数,
这个运算符表示为每个
。
。让我们求出
和
使得
,同时
在所有可能的情况下的值应该最小。
解题思路: 我们的思路十分简单,为了尽量让a和b相差最小即可。我们遍历就行,然后我们确定遍历的时候尽量平分x的位置上的数,那么当x上位数为1时也就不能平分了,我们必须要分给一个a为0,一个b为1.那么这个时候大小就出现差异了。那么我们接下来的遍历就要弥补之间的差距,于是将x后面的全部给a,b补0即可。这样a和b的差距就会最小,也就是能够是
最小,所以我们关键要设一个标志变量判断是否开始出现差异。具体看代码。
AC代码:
/*
*blo
*注谢谢支持。
*
*/
//POJ不支持
//i为循环变量,a为初始值,n为界限值,递增
//i为循环变量, a为初始值,n为界限值,递减。
using namespace std;
const int inf = 0x3f3f3f3f;//无穷大
const int maxn = 5e5+4;//最大值。
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
//*******************************分割线,以上为自定义代码模板***************************************//
int t,n;//t组测试样例,n为长度
char s1[maxn],s2[maxn],s3[maxn];//字符串。
int main(){
//freopen("in.txt", "r", stdin);//提交的时候要注释掉
IOS;
while(cin>>t){
while(t--){
cin>>n;
cin>>s1;
int cnt=0;
int flag=false;
s2[cnt]='1';
s3[cnt++]='1';
rep(i,1,n-1){
if(s1[i]=='0'){
s2[cnt]='0';
s3[cnt++]='0';
}
else if(!flag){
if(s1[i]=='1'){
s2[cnt]='1';s3[cnt++]='0';
flag=true;
}
else{
s2[cnt]='1';s3[cnt++]='1';
}
}
else{
if(s1[i]=='1'){
s2[cnt]='0';s3[cnt++]='1';
}
else{
s2[cnt]='0';s3[cnt++]='2';
}
}
}
s2[cnt]='\0';s3[cnt]='\0';
cout<<s2<<endl;
cout<<s3<<endl;
}
}
return 0;
}