srm 546

欢迎点此观看QvQ

250


Solution

考虑奇偶性,每次定一个可以变成该数的上下界,按二进制位考虑即可

Code

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define F first
#define S second
typedef long long LL;
typedef pair<int, int> pii;
struct KleofasTail {
    LL gao(LL x, LL k) {
        if (k > x)  return 0;
        if (k <= 1) return x - k + 1;
        LL kk = k + (k % 2 == 0);
        LL t = 0;
        while (k <= x) {
            t += min(x, kk) - k + 1;
            k <<= 1;
            kk = (kk << 1 | 1);
        }
        return t;
    }
    long long countGoodSequences(long long K, long long A, long long B) {
        return gao(B, K) - gao(A - 1, K);              
    }
};

500


Description

求满足大于 A(A1015) 的且 digit1 至少出现 count1 次, digit2 至少出现 count2 的最小的数是多少?
(count1+count215,digit1,digit210)

Solution

很容易想到数位 dp ,常见数位 dp 套路,用一个 f 表示当前数是否与最小值相等,还有cnt1x1,cnt2x2没有用,是否成立。
正常转移即可,注意一点,除了 x1,x2,lim,lim+1 以外,其他数是没什么意义的, dp 即可

Code

#include <bits/stdc++.h>//dp
using namespace std;
#define pb push_back
#define mp make_pair
#define F first
#define S second
typedef long long LL;
typedef pair<int, int> pii;
int a[16];
LL ans;
struct FavouriteDigits {
    bool dfs(int p, bool f, int x1, int cnt1, int x2, int cnt2, LL now) {
        if (p == -1) {
            if (cnt1 <= 0 && cnt2 <= 0) {
                ans = now;
                return 1;
            }
            return 0;
        }
        int lim = f ? a[p] : 0;
        for (int i = lim; i <= 9; ++i) {
            if (f) {
                if (!(i == lim || i == x1 || i == x2 || i == lim + 1))  continue;
            }
            else {
                if (!(i == lim || i == x1 || i == x2))  continue;
            }
            int d1 = cnt1 - (i == x1);
            int d2 = cnt2 - (i == x2);
            if (!now && !x1)    d1 = cnt1;
            if (dfs(p - 1, f & (i == lim), x1, d1, x2, d2, now * 10 + i))   return 1;
        }
        return 0;
    }
    long long findNext(long long N, int x1, int cnt1, int x2, int cnt2) {
        if (x1 > x2)    swap(x1, x2), swap(cnt1, cnt2);
        int p = 0;
        while (N) {
            a[p++] = N % 10;
            N /= 10;
        }
        p = max(p, cnt1 + cnt2);
        dfs(p, 1, x1, cnt1, x2, cnt2, 0);
        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值