题目链接 给出一个数,允许最多k次将某对位置的两个数字交换,问可生成的最小和最大的数是多少。
此题,贪心的解法是个假解法。。。。举个栗子,k=2时的970979,贪心的求出最大值是999077,但实际上可以达到的最大值是999770。所以这题必然不是个贪心。。。
最长只有9位,考虑遍历原数所有的排列,如果能由原数在k次之内变换而来,就尝试更新答案。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <map>
#include <vector>
#include <iostream>
#include <algorithm>
#define INF 0x3f3f3f3f
#define eps 1e-8
using namespace std;
typedef long long ll;
const int maxn = 105;
const ll mod = 1000000007;
int kase, n, k, sum[maxn];
int num[15], ans1[15], ans2[15];
int pre[maxn], minn, maxx;
char s[15];
void update()
{
if(num[pre[1]] == 0) return;
for(int i = 1;i <= n;i++) ans1[i] = pre[i];
int cnt = 0, t = 0;
for(int i = 1;i <= n;i++)
{
t = t*10 + num[pre[i]];
if(ans1[i] != i)
{
for(int j = i + 1;j <= n;j++)
{
if(ans1[j] == i)
{
swap(ans1[i], ans1[j]);
cnt++;
if(cnt > k) return;
break;
}
}
}
}
if(cnt > k) return;
minn = min(minn, t);
maxx = max(maxx, t);
}
int main()
{
scanf("%d", &kase);
while(kase--)
{
scanf("%s%d", s + 1, &k);
n = strlen(s + 1);
memset(ans1, 0, sizeof(ans1));
memset(ans2, 0, sizeof(ans2));
for(int i = 1;i <= n;i++)
{
num[i] = s[i]- '0';
ans1[num[i]]++;
ans2[num[i]]++;
}
if(k >= n - 1)
{
for(int i = 1;i <= 9;i++)
{
if(ans1[i])
{
printf("%d", i);
ans1[i]--;
break;
}
}
for(int i = 0;i <= 9;i++)
{
while(ans1[i])
{
printf("%d", i);
ans1[i]--;
}
}
printf(" ");
for(int i = 9;i >= 0;i--)
{
while(ans2[i])
{
printf("%d", i);
ans2[i]--;
}
}
printf("\n");
continue;
}
for(int i = 1;i <= n;i++)
pre[i] = i;
minn = 2e9, maxx = -1;
do
{
update();
}while(next_permutation(pre + 1, pre + n + 1));
printf("%d %d\n", minn, maxx);
}
return 0;
}