第一章最后一部分了,后面的大概要开始变得更难了。
Nunber Triangles
经典的 dp 题, 可以用记忆化搜索也可以用递推, 我用的是记忆化搜索。
#include <bits/stdc++.h>
using namespace std;
const int N = 1005;
int f[N][N], n, a[N][N];
int get(int r, int c) {
if (r == n) return 0;
if (~ f[r][c]) return f[r][c];
return f[r][c] = a[r][c] + max(get(r + 1, c), get(r + 1, c + 1));
}
int main() {
freopen("numtri.in", "r", stdin);
freopen("numtri.out", "w", stdout);
memset(f, 0xff, sizeof f);
scanf("%d", &n);
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++) {
scanf("%d", &a[i][j]);
}
}
printf("%d\n", get(0, 0));
}
Prime Palindromes
问范围内既是素数又是回文数的有哪些。
存一遍上限内回文数的表,判断他们是不是素数。
#include <bits/stdc++.h>
using namespace std;
const int N = 10005;
bool v[N];
vector <int> p, w;
void init1() {
for (int i = 2; i < N; i++) {
if (v[i]) continue;
p.push_back(i);
for (int j = i + i; j < N; j += i) v[j] = 1;
}
}
bool prime(int x) {
if (x < N) return v[x] == 0;
for (int i = 0; p[i] * p[i] <= x && i < p.size(); i++) {
if (x % p[i] == 0) return 0;
}
return 1;
}
int len(int x) {
int l = 0;
while (x) l++, x /= 10;
return l;
}
int trans(int x, int t) {
int n = len(x), a = x;
if (t) n--, a /= 10;
while (n--) {
x = x * 10 + a % 10;
a /= 10;
}
return x;
}
void init2(int a, int b, int t) {
for (int i = 1;; i++) {
int x = trans(i, t);
if (x < a) continue;
if (x > b) break;
w.push_back(x);
}
}
int main() {
freopen("pprime.in", "r", stdin);
freopen("pprime.out", "w", stdout);
int a, b;
scanf("%d %d", &a, &b);
init1();
init2(a, b, 0);
init2(a, b, 1);
sort(w.begin(), w.end());
for (int i = 0; i < w.size(); i++) {
if (prime(w[i])) printf("%d\n", w[i]);
}
}
SuperPrime Rib
问前缀都是素数的 N 位数有哪些。
直接dp
#include <bits/stdc++.h>
using namespace std;
const int N = 10005;
bool v[N];
int a[200005], b[200005];
vector <int> p;
void init() {
for (int i = 2; i < N; i++) {
if (v[i]) continue;
p.push_back(i);
for (int j = i + i; j < N; j += i) v[j] = 1;
}
}
bool prime(int x) {
if (x < N) return v[x] == 0;
for (int i = 0; p[i] * p[i] <= x && i < p.size(); i++) {
if (x % p[i] == 0) return 0;
}
return 1;
}
int main() {
freopen("sprime.in", "r", stdin);
freopen("sprime.out", "w", stdout);
init();
a[0] = 2; a[1] = 3; a[2] = 5; a[3] = 7;
int *now = a, *pre = b;
int len, m = 4;
int n;
scanf("%d", &n);
for (int i = 1; i < n; i++) {
len = m; m = 0;
swap(pre, now);
for (int j = 0; j < len; j++) {
for (int k = 1; k < 10; k += 2) {
int x = pre[j] * 10 + k;
if (prime(x)) now[m++] = x;
}
}
}
sort(now, now + m);
unique(now, now + m);
for (int i = 0; i < m; i++) printf("%d\n", now[i]);
}