【2018多校Beautiful Now HDU - 6351】【dfs+剪枝】

【链接】

http://acm.hdu.edu.cn/showproblem.php?pid=6351

【题意】

大意就是给你一个数n,求在最多k次得交换下,能够得到的最大的数和最小得数是多少,且数不能有前导0

【分析】

数的大小不超过1e9,也就是9位数字。

显然地,n个数至多交换n-1次能变成有序。

然后dfs+剪枝,有序地交换两个数.

【代码】

#include<bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
char s[11];
int n[11];
int len;
int mi, ma;
int k;

void fmin() {
	int a[11];
	int cnt = 0;
	for (int i = 0; i < len; i++) {
		if (s[i]=='0')cnt++;
		n[i] = s[i] - '0';
	}
	sort(n, n + len);
	printf("%d", n[cnt]);
	for (int i = 0; i < cnt; i++)printf("0");
	for (int i = cnt + 1; i < len; i++)printf("%d", n[i]);
	printf(" ");

}

void fmax() {
	int a[11];
	int cnt = 0;
	for (int i = 0; i < len; i++) {
		if (!s[i])cnt++;
		n[i] = s[i] - '0';
	}
	sort(n, n + len);
	for (int i = len - 1; i >= 0; i--) {
		printf("%d", n[i]);
	}
	printf("\n");
}

int fun(int n[]) {
	int res = 0;
	for (int i = 0; i < len; i++) {
		res = res * 10 + n[i];
	}
	return res;
}

void dfs(int tmp[],int cur, int num) {
	if (cur ==len-1 || num == k) {
		int u = fun(tmp);
		mi = min(mi, u);
		ma = max(ma, u);
		return;
	}
	int u = fun(tmp);
	mi = min(mi, u);
	ma = max(ma, u);
	for (int i = cur + 1; i < len; i++) {
		if (cur == 0 && tmp[i] == 0)continue;
		swap(tmp[cur], tmp[i]);
		dfs(tmp,cur + 1, num + 1);
		swap(tmp[cur], tmp[i]);
	}
	dfs(tmp,cur+1, num);
	return;
}

int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		scanf("%s%d", s, &k);
		len = strlen(s);
		mi = inf;
		ma = 0;
		if (k >= len - 1) {
			fmin();
			fmax();
		}
		else {
			for (int i = 0; i < len; i++) {
				n[i] = s[i] - '0';
			}
			dfs(n,0, 0);printf("%d %d\n", mi, ma);
		}
	}
}

猜你喜欢

转载自blog.csdn.net/running_acmer/article/details/83352117