题目链接:http://www.topcoder.com/stat?c=problem_statement&pm=10342
题目大意:给定两个数x和y,通过对x和y某些位交换后,使得x*y的结果最大,交换次数给定
解题思路:因为x和y对应位不管怎么交换,x+y的值保持不变,所以要使x*y最大,只要是x和y之间的距离最小就可以。如何寻找最小距离的x和y呢?首先假设x>y,从左到右扫描,找到第一个x[i]<y[i],使他们交换过来,继续扫描,后面的每位都保证x[i]<y[i],并记录下交换的次数n和是否有某位相同的情况。如果n=swaps,则即为最大的;如果n<swaps,还得继续,如果有某位相同,则剩下的交换都交换这里就可以,如果没有相同的位,则判断剩下的交换次数是否是偶数,如果是,则通过对某个对应位,反复交换,不改变x和y,如果不是,只要把最后一个改变的位交换过来就可以;如果n>swaps,从数位较小的开始,对已经改变的变回去,操作n-swaps就可以。由于变与不变是相对的,所以通过计算两次,(x,y)和(y,x),并去最大的那个结果。注意最大的结果不是字符串较大的那个。
//keep x>y
for (i = 0;i < n;i++)
{
if (x[i]>y[i])
{
break;
}
else if(x[i]<y[i])
{
swap(x[i],y[i]);
n1++;
f[i]=true;
break;
}
else
{
flag=true;
}
}
//keep the diff of x and y smallest
for (i++;i < n;i++)
{
if (x[i] > y[i])
{
swap(x[i],y[i]);
n1++;
f[i]=true;
}
else if (x[i] == y[i] && flag == false)
{
flag=true;
}
}
//adjust according the swaps and n1
if (n1 < swaps)
{
if (flag==false&&(swaps-n1)%2!=0)
{
swap(x[n-1],y[n-1]);
}
}
else if (n1 > swaps)
{
int count=0;
for (i=n-1;i>=0&&count<n1-swaps;i--) //count后没有等号
{
if(f[i]==true)
{
swap(x[i],y[i]);
count++;
}
}
}
string temp=mult(x,y);
//cout<<temp<<endl;
return temp;
}
string maximalProduct(string x,string y,int swaps)
{
string ans1=function(x,y,swaps);
string ans2=function(y,x,swaps);
//返回较大的,注意不是直接字符串比较
if(ans1.size()>ans2.size())
return ans1;
else if(ans1.size()<ans2.size())
return ans2;
else
{
for(int i=0;i<ans1.size();i++)
if(ans1[i]>ans2[i]) return ans1;
else if(ans1[i]<ans2[i]) return ans2;
return ans1;
}
}
};
int main()
{
string x,y;
int s;
DigitsSwap temp;
while(1)
{
cin>>x;
cin>>y;
cin>>s;
cout<<temp.maximalProduct(x,y,s)<<endl;
}
}