Question A.Fast Bit Calculations
#include <iostream> #include <cstring> long long int f[40][2][40]; //f[i][j][0]表示当前枚举到了第i位且前一位为j,并且这个数目前含几个连续11 long long int len; //数的长度 long long int bit[40]; //存储每一位 using namespace std; long long int dfs(int pos, int last, int have, bool limit) //have目前含几个连续11 { if (pos < 0) return have; if (!limit && ~f[pos][last][have]) return f[pos][last][have]; int x = limit ? bit[pos] : 1; long long int res = 0; for (int i = 0; i <= x; i++) { long long int newh = have; if (last == 1 && i == 1) newh++; res += dfs(pos - 1, i, newh, limit && i == x); } return limit ? res : f[pos][last][have] = res; } long long int get(long long int n) { len = 0; while (n) { bit[len++] = n % 2; n /= 2; } return dfs(len - 1, 0, 0, 1); //最后一个是limit } int main() { int n, t; cin >> t; for (int i = 1; i <= t; i++) { memset(f, -1, sizeof f); cin >> n; cout << "Case " << i << ": " << get(n) << endl; } return 0; }
Question B.Round Numbers
#include <iostream> #include <cstring> long long int f[100][100][100]; //f[当前位][目前有多少个0][目前有多少个1] int len, bit[100]; using namespace std; long long int dfs(int loc, int zero, int one, bool limit, bool first) //first:当前是不是首位 { if (loc < 0) return (zero >= one); if (!limit && ~f[loc][zero][one]) return f[loc][zero][one]; int x = limit ? bit[loc] : 1; long long int ans = 0; for (int i = 0; i <= x; i++) { if (first == 1) { if (i == 0) //首位且第一位是0 ans += dfs(loc - 1, 0, 0, limit && i == x, 1); else if (i == 1) ans += dfs(loc - 1, zero, one + 1, limit && i == x, 0); } else if (first == 0) { if (i == 0) ans += dfs(loc - 1, zero + 1, one, limit && i == x, 0); else if (i == 1) ans += dfs(loc - 1, zero, one + 1, limit && i == x, 0); } } return limit ? ans : f[loc][zero][one] = ans; } long long int get(long long int n) { int len = 0; while (n) { bit[len++] = n % 2; n /= 2; } return dfs(len - 1, 0, 0, 1, 1); } int main() { memset(f, -1, sizeof f); long long int l, r; cin >> l >> r; cout << get(r) - get(l - 1); return 0; }
Question C.How Many Zeroes?
#include <iostream> #include <cstring> long long int f[100][100]; //f[当前位][目前有多少个0] int len, bit[100]; using namespace std; long long int dfs(int loc, int zero, bool limit, bool first) //first:当前是不是首位 { if (loc < 0) return first ? 1 : zero; if (!first && !limit && ~f[loc][zero]) return f[loc][zero]; int x = limit ? bit[loc] : 9; long long int ans = 0; for (int i = 0; i <= x; i++) { if (first == 1 && i == 0) ans += dfs(loc - 1, 0, limit && x == i, 1); else if (i == 0) ans += dfs(loc - 1, zero + 1, limit && x == i, 0); else ans += dfs(loc - 1, zero, limit && x == i, 0); } if (!first && !limit) f[loc][zero] = ans; return ans; } long long int get(long long int n) { int len = 0; if (n == 0) return 1; while (n) { bit[len++] = n % 10; n /= 10; } return dfs(len - 1, 0, 1, 1); } int main() { long long int l, r; int t; cin >> t; for (int i = 1; i <= t; i++) { memset(f, -1, sizeof f); cin >> l >> r; cout << "Case " << i << ": "; cout << get(r) - get(l - 1) << endl; } return 0; }
Question D.Beautiful numbers
#include <cstring> #include <iostream> #include <algorithm> int t[2525], cnt; long long f[20][50][2520]; int len, bit[20]; using namespace std; int gcd(int a, int b) { if (b == 0) return a; return gcd(b, a % b); } int lcm(int a, int b) { int c = gcd(a, b); return a * b / c; } long long dfs(int pos, int last, int mod, bool limit) { if (pos < 0) return !(mod % last); if (!limit && f[pos][t[last]][mod] != -1) return f[pos][t[last]][mod]; int x = limit ? bit[pos] : 9; long long res = 0; for (int i = 0; i <= x; i++) { int newlast = last; if (i) newlast = lcm(last, i); res += dfs(pos - 1, newlast, (mod * 10 + i) % 2520, limit && i == x); } return limit ? res : f[pos][t[last]][mod] = res; } long long get(long long n) { len = 0; while (n) { bit[len++] = n % 10; n /= 10; } return dfs(len - 1, 1, 0, 1); } int main() { memset(f, -1, sizeof f); for (int i = 1; i <= 2520; i++) if (2520 % i == 0) t[i] = ++cnt; int t; cin >> t; while (t--) { long long l, r; cin >> l >> r; cout << get(r) - get(l - 1) << endl; } return 0; }
Question E.不要62
#include<cstring> #include<iostream> #include<algorithm> using namespace std; int f[10][2]; int len, bit[10]; int dfs(int pos, bool last, bool limit) { if (pos < 0) return 1; if (!limit && ~f[pos][last]) return f[pos][last]; int x = limit ? bit[pos] : 9; int res = 0; for (int i = 0; i <= x; i++) { if (i == 4 || last && i == 2) continue; res += dfs(pos - 1, i == 6, limit && i == x); } if (!limit) f[pos][last] = res; return res; } int get(int n) { bit[0] = 0; len = 0; while (n) bit[len++] = n % 10, n /= 10; return dfs(len - 1, 0, 1); } int main() { memset(f, -1, sizeof f); int l, r; while (cin >> l >> r, l) cout << get(r) - get(l - 1) << endl; return 0; }
Question F.Bomb
#include <iostream> #include <cstring> using namespace std; long long f[40][20][40]; //这一位的位置,上一位是啥,现在有多少49 int len, bit[40]; long long dfs(int pos, int last, int how, bool limit) { if (pos < 0) return (how > 0); if (!limit && ~f[pos][last][how]) return f[pos][last][how]; int x = limit ? bit[pos] : 9; long long ans = 0; for (int i = 0; i <= x; i++) { if (i == 9 && last == 4) ans += dfs(pos - 1, i, how + 1, limit && i == x); else ans += dfs(pos - 1, i, how, limit && i == x); } return limit ? ans : f[pos][last][how] = ans; } long long get(long long n) { len = 0; while (n) { bit[len++] = n % 10; n /= 10; } return dfs(len - 1, 0, 0, 1); } int main() { int t; long long n; cin >> t; while (t--) { cin >> n; memset(f, -1, sizeof f); cout << get(n) << endl; } return 0; }
Question G.吉哥系列故事——恨7不成妻
#include <iostream> #include <cstring> #define ll long long using namespace std; ll l, r; struct Node { ll num, sum, sqsum; }dp[20][10][10]; int d[20], len, t; ll p[20]; const ll mod = 1e9 + 7; Node dfs(int v, int sum, int num, bool flag) { if (v <= 0) { Node tmp; tmp.num = (num != 0 && sum != 0); tmp.sum = 0; tmp.sqsum = 0; return tmp; } if (!flag && dp[v][sum][num].num != -1) return dp[v][sum][num]; int up = flag ? d[v] : 9; Node ans; ans.num = ans.sum = ans.sqsum = 0; for (int i = 0; i <= up; i++) { if (i == 7) continue; Node tmp = dfs(v - 1, (sum + i) % 7, (num * 10 + i) % 7, flag && (i == up)); ans.num += tmp.num; ans.num %= mod; ll newU = p[v - 1] * i % mod; ans.sum += (tmp.sum + newU * tmp.num % mod) % mod; ans.sum %= mod; ans.sqsum += ((tmp.sqsum + 2 * newU * tmp.sum % mod) % mod + tmp.num * newU % mod * newU % mod) % mod; ans.sqsum %= mod; } if (!flag) dp[v][sum][num] = ans; return ans; } ll get(ll num) { len = 0; while (num) { d[++len] = num % 10; num /= 10; } return dfs(len, 0, 0, 1).sqsum; } int main() { memset(dp, -1, sizeof(dp)); p[0] = 1; for (int i = 1; i < 20; i++) { p[i] = (p[i - 1] * 10) % mod; } cin >> t; while (t--) { scanf("%lld %lld", &l, &r); printf("%lld\n", (get(r) - get(l - 1) + mod) % mod); } return 0; }
Question H.B-number
#include <iostream> #include <cstring> int f[10][10][13][2]; int len, bit[10]; using namespace std; int dfs(int pos, int last, int mod, bool flag, bool limit) { if (pos < 0) return !mod && flag; if (!limit && ~f[pos][last][mod][flag]) return f[pos][last][mod][flag]; int x = limit ? bit[pos] : 9; int res = 0; for (int i = 0; i <= x; i++) { bool newf = flag; if (last == 1 && i == 3) newf = 1; res += dfs(pos - 1, i, (mod * 10 + i) % 13, newf, limit && i == x); } return limit ? res : f[pos][last][mod][flag] = res; } int get(int n) { len = 0; while (n) { bit[len++] = n % 10; n /= 10; } return dfs(len - 1, 0, 0, 0, 1); } int main() { memset(f, -1, sizeof f); int n; while (cin >> n) cout << get(n) << endl; return 0; }
如有疏漏之处请指出,感谢!