《Divisibility by Eight》

非常好的一个题。

如果不是看到dp的tag,我可能真不会往dp去想。

首先状压去枚举肯定不行,因为最多100位。

经过仔细思考之后我得出了一个dp状态。

dp[i][j][k] - 表示a[i]为第j位且余数为k的值。

在验证过后,我发现这个状态很可做。

然后就开始推了,并不是很难推,但是这里有一个问题,这个数太大存不下。

所以我一开始用了python去写,但是python的三维数组存在了一个值覆盖的问题,怎么都写不对。

于是我开始思考,直接用string去存答案即可,然后在中间所有情况都只去记录一个模数就行了。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const int N = 1e5 + 5;
const int M = 1e3 + 5;
const LL Mod = 1000000;
#define pi acos(-1)
#define INF 1e12
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read(){
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
}
using namespace FASTIO;

string dp[105][105][10],ans;//dp[i][j][k] - i为第j位对8取模的余数为k
int a[105];
LL quick_mi(LL a,LL b){
    LL re = 1;
    while(b){
        if(b & 1) re = re * a % 8;
        a = a * a % 8;
        b >>= 1;
    }
    return re;
}
int main()
{
    string s;cin >> s;
    int n = s.size(),len = 0,f = 0;
    for(int i = s.size() - 1;i >= 0;--i) a[++len] = s[i] - '0';
    for(int i = 1;i <= n;++i) {
        if(a[i] == 0) {
            f = 1;
            break;
        }
    }
    if(f) {
        printf("YES\n0\n");
    }
    else {
        for(int i = 1;i <= n;++i) {
            for(int j = 1;j <= i;++j) {
                int ma = quick_mi(10,j - 1) * a[i] % 8;
                if(j == 1) {
                    dp[i][j][ma] = a[i] + '0';
                }
                else {
                    for(int k = 0;k < 8;++k) {
                        for(int m = 1;m < i;++m) {
                            if(dp[m][j - 1][k].size() != 0){
                                int yu = (k + ma) % 8;
                                char c = a[i] + '0';
                                dp[i][j][yu] = c;
                                dp[i][j][yu] += dp[m][j - 1][k];
                            }
                        }
                    }
                }
                if(dp[i][j][0].size() != 0){
                    ans = dp[i][j][0];
                }
            }
        }
        if(ans.size() != 0) cout << "YES" << "\n" << ans << "\n";
        else printf("NO\n");
    }
    system("pause");
    return 0;
}
View Code

 

posted @ 2021-02-14 08:38  levill  阅读(48)  评论(0编辑  收藏  举报