1. 程式人生 > >【2018多校Beautiful Now HDU

【2018多校Beautiful Now HDU

【連結】

【題意】

大意就是給你一個數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);
		}
	}
}