欢迎点此观看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(A≤1015)
的且
digit1
至少出现
count1
次,
digit2
至少出现
count2次
的最小的数是多少?
(count1+count2≤15,digit1,digit2≤10)
Solution
很容易想到数位
dp
,常见数位
dp
套路,用一个
f
表示当前数是否与最小值相等,还有
正常转移即可,注意一点,除了
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;
}
};