Beautiful Now
题意
给出一个最大为10^9的数字n,以及一个k,你最多交换n中任意两个位置的数字k次,问形成的最大数字和最小数字。
思路
看到这题,我靠这题暴力交换一下,不难啊,咋没人做。。
后来发现是我菜了,贪心写完成功WA了,比如这个样例970970 2,最小值不对。
正解是暴力,进行全排列,检验某个排列是否合法。
n最大是10^9所以枚举次数最多为9!(362880)*9,复杂度可以接受。
(昨天被自己傻到了,搞了两次全排列一个求最大值一个求最小值。。。)
代码
//#include<bits/stdc++.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<math.h>
#define pb push_back
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e5+10;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
const double eps=1e-14;
int arr[N],brr[N],crr[N],pos[10];
int cnt,x,k;
int check()
{
for(int i=1;i<=cnt;i++)
{
brr[i]=crr[i];
pos[brr[i]]=i;
}
int ans=0;
for(int i=1;i<=cnt;i++)
{
if(brr[i]!=i)
{
ans++;
if(ans>k) return 0;
pos[brr[i]]=pos[i];
swap(brr[i],brr[pos[i]]);
}
}
return ans<=k;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
cnt=0;
scanf("%d%d",&x,&k);
int maxn=x,minn=x;
while(x)
{
arr[++cnt]=x%10;
x/=10;
}
for(int i=1; i<=cnt; i++)
crr[i]=i;
do
{
if(arr[crr[cnt]]==0||(!check()))
continue;
int tmp=0;
for(int i=cnt; i; i--)
tmp=tmp*10+arr[crr[i]];
minn=min(minn,tmp);
maxn=max(maxn,tmp);
}
while(next_permutation(crr+1,crr+1+cnt));
printf("%d %d
",minn,maxn);
}
return 0;
}