AtCoder Beginner Contest 154
AtCoder Beginner Contest 154
https://atcoder.jp/contests/abc154
今天也比较简单。
E - Almost Everywhere Zero
贪心或者数位dp。
(其实我这个贪心应该就是在模拟数位dp)
贪心
#include <bits/stdc++.h>
#define ll long long
using namespace std;
string s;
int k, n;
ll sum = 0;
int main () {
cin >> s >> k;
n = s.size ();
if (k == 1) {
sum = 9ll * (n - 1) + (s[0] - '0');
}
else if (k == 2) {
sum = max(0ll, 81ll * (n - 2) * (n - 1) / 2);
sum += 9ll * (s[0] - '0' - 1) * (n - 1);
//3...
//cout << sum << ' ';
bool find = false;
for (int i = 1; i < n; i++) {
if (s[i] != '0') {
find = true;
sum += max(0ll, 9ll * (n - i - 1)) + (s[i] - '0');
break;
}
}
//if (!find) sum += 9ll * (s[0] - '0') * (n - 1);
if (n == 1) sum = 0;
}
else { // k == 3
for (int i = 2; i <= n - 2; i++) sum += 729ll * i * (i - 1) / 2;
sum += max(0ll, 81ll * (s[0] - '0' - 1) * (n - 1) * (n - 2) / 2);
for (int i = 1; i < n; i++) {
if (s[i] != '0') {
sum += max(0ll, 81ll * (n - i - 1) * (n - i - 2) / 2) + max(0ll, 9ll * (s[i] - '0' - 1) * (n - i - 1));
for (int j = i + 1; j < n; j++) {
if (s[j] != '0') {
sum += max (0ll, 9ll * (n - j - 1)) + max (0, s[j] - '0');
break;
}
}
break;
}
}
if (n < 3) sum = 0;
}
cout << sum;
}
数位dp
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 105;
ll K, n, a[N], f[N][2][10]; //f[i][j][k]:最高i位,0/1达到上界与否,非0整数的个数
string s;
int main() {
cin >> s >> K;
n = s.size();
s = ' ' + s;
for (int i = 1; i <= n; i++) a[i] = s[i] - '0';
f[0][1][0] = 1;
for (int i = 0; i < n; i++) { //1-n的前一位
for (int j = 0; j <= 1; j++) { //是否达到上限
for (int k = 0; k <= K; k++) { //非0整数的个数
for (int l = 0; l <= 9; l++) { //第i位的整数
if (j == 1 && l > a[i + 1]) break; //比上限大
if (k == K && l > 0) break; //非0整数已放完k个且当前为不为0,则不用再放下去
ll kk = k + (bool)l, jj = (j == 1 && a[i + 1] == l);
f[i + 1][jj][kk] += f[i][j][k];
}
}
}
}
cout << f[n][0][K] + f[n][1][K];
}
F - Many Many Paths
利用了组合数的一个小公式:
转化为前缀和相减的形式即可求出:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 2e6 + 5, mod = 1e9 + 7;
ll r1, r2, c1, c2;
ll fact[N], infact[N];
ll qmi(ll a, ll k, ll p){
ll res = 1;
while(k){
if(k & 1)
res = (ll)res * a % p;
a = (ll)a * a % p;
k >>= 1;
}
return res;
}
ll C (int a, int b) {
if (a < b) return 0;
return fact[a] * infact[b] % mod * infact[a - b] % mod;
}
void init () {
fact[0] = infact[0] = 1;
for(int i = 1; i < N; i++){
fact[i] = (ll)fact[i-1] * i % mod;
infact[i] = (ll)infact[i-1] * qmi(i, mod - 2,mod) % mod;
}
}
int main() {
init ();
cin >> r1 >> c1 >> r2 >> c2;
ll sum = 0;
for (int i = r1; i <= r2; i++) {
(sum += C (i + c2 + 1, i + 1) - C(i + c1, i + 1) + mod) %= mod;
}
cout << sum;
}
//求\sum_{i=r1}^r2 \sum_{j=c1}^c2(C_{i+j}^i))