题意:给出一个数U (1 ≤ U ≤ 1018),求一个最大的比U小的数,这个数要满足在此数中出现的每个数字不超过2次。
思路:dfs搜索,维护一个数组记录当前每个数字已经出现了多少次。
1 //#include <bits/stdc++.h> 2 #include <cstring> 3 #include <cstdio> 4 #include <string> 5 #include <iostream> 6 using namespace std; 7 long long U; 8 int num[20]; 9 int ans[20]; 10 int mark[12]; 11 int len; 12 bool Find; 13 void dfs(int cur, int limit) 14 { 15 if(Find) return; 16 if(cur < 0) 17 { 18 bool flag = true; 19 for(int i = len-1; i >= 0; i--) 20 { 21 if(flag && ans[i] == 0) continue; 22 else if(flag && ans[i] != 0) 23 { 24 printf("%d", ans[i]); 25 flag = false; 26 } 27 else printf("%d", ans[i]); 28 } 29 printf("\n"); 30 Find = true; 31 return; 32 } 33 int up = limit?num[cur]:9; 34 for(int i = up; i >= 0; i--) 35 { 36 if(mark[i] >= 2) continue; 37 mark[i]++; 38 ans[cur] = i; 39 dfs(cur-1, limit && i == up); 40 if(Find) return; 41 mark[i]--; 42 } 43 return; 44 45 } 46 void slove(long long x) 47 { 48 len = 0; 49 while(x) 50 { 51 num[len++] = x % 10; 52 x /= 10; 53 } 54 memset(mark, 0, sizeof(mark)); 55 dfs(len-1, 1); 56 } 57 int main() 58 { 59 // freopen("in.txt", "r", stdin); 60 // freopen("out.txt", "w", stdout); 61 while(~scanf("%lld", &U)) 62 { 63 Find = false; 64 slove(U); 65 } 66 return 0; 67 }