目录

20190811 小L的数——number

20190811 小L的数——number

思路:

观察可得答案一定小于等于$4$,因为用$08,04,02,01$一定可以组合出每一个数,我们只要判断答案为$1,2$还是$3$,若都不是,则答案为$4$。 考虑枚举是由那些数字组成的喜欢的数来构成的答案,然后通过$dp$验证即可。

代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include<bits/stdc++.h>
#define ll long long
#define pb push_back
using namespace std;
ll x;
int t, na, ans, a[23], su, va[20010], g[110], ng, s[55][55][55], dp[20010][22];
bool vi[20010][34];
vector<int> n1[20010];
int main()
{
    //freopen("number.in", "r", stdin);
    //freopen("number.out", "w", stdout);
    for (int i = 0; i <= 8; i++)
        for (int j = i + 1; j <= 9; j++)g[++ng] = i * 10 + j;
    memset(vi, 0, sizeof(vi));
    for (int i = 0; i <= ng; i++)
    {
        for (int j = i; j <= ng; j++)
        {
            for (int k = j; k <= ng; k++)
            {
                va[++su] = 3;
                if (k == 0)va[su]--;
                if (j == 0)va[su]--;
                if (i == 0)va[su]--;
                vi[su][g[i] / 10 + g[j] / 10 + g[k] / 10] = 1;
                vi[su][g[i] / 10 + g[j] / 10 + g[k] % 10] = 1;
                vi[su][g[i] / 10 + g[j] % 10 + g[k] / 10] = 1;
                vi[su][g[i] / 10 + g[j] % 10 + g[k] % 10] = 1;
                vi[su][g[i] % 10 + g[j] / 10 + g[k] / 10] = 1;
                vi[su][g[i] % 10 + g[j] / 10 + g[k] % 10] = 1;
                vi[su][g[i] % 10 + g[j] % 10 + g[k] / 10] = 1;
                vi[su][g[i] % 10 + g[j] % 10 + g[k] % 10] = 1;
                s[i][j][k] = s[j][i][k] = s[j][k][i] = s[k][j][i] = s[i][k][j] = s[k][i][j] = su;
                if (s[i][j][0] != su)n1[su].pb(s[i][j][0]);
                if (s[i][0][k] != su)n1[su].pb(s[i][0][k]);
                if (s[0][j][k] != su)n1[su].pb(s[0][j][k]);
                if (s[i][0][0] != su)n1[su].pb(s[i][0][0]);
                if (s[0][0][k] != su)n1[su].pb(s[0][0][k]);
                if (s[0][j][0] != su)n1[su].pb(s[0][j][0]);
                if (s[0][0][0] != su)n1[su].pb(s[0][0][0]);
            }
        }
    }
    cin >> t;
    while (t--)
    {
        memset(dp, 0, sizeof(dp));
        cin >> x;
        na = 0, ans = 4;
        while (x)
        {
            a[++na] = x % 10;
            x /= 10;
        }
        for (int i = 1; i <= su; i++)dp[i][na + 1] = 1;
        for (int i = na; i >= 1; i--)
        {
            for (int j = 1; j <= su; j++)
            {
                for (int la = 0; la <= 2; la++)
                    if (dp[j][i + 1] & (1 << la))
                        for (int no = 0; no <= 2; no++)
                            if (la * 10 + a[i] - no >= 0 && vi[j][la * 10 + a[i] - no])dp[j][i] |= (1 << no);
                for (auto k : n1[j])dp[j][i] |= dp[k][i];
            }
        }
        for (int i = 1; i <= su; i++)if (dp[i][1] & 1)
            {
                ans = min(ans, va[i]);
                break;
            }
        cout << ans << endl;
    }
    return 0;
}