uvalive 7203 At most twice

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5215

题意:给出一个数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 }

 

posted @ 2016-03-03 19:57  下周LGD该赢了吧  阅读(418)  评论(0编辑  收藏  举报