HDU 6351 Beautiful Now (並不是貪心)
阿新 • • 發佈:2019-01-09
題目連結 給出一個數,允許最多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; }