BestCoder #18
A 傻缺题,直接先把素数搞出来然后枚举一下就好了。
#include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; const int maxn = 1e4 + 10; bool vis[maxn]; vector<int> pnum; void init() { vis[1] = true; int maxv = 10000; for(int i = 2; i <= maxv; i++) if(!vis[i]) { pnum.push_back(i); for(int j = i + i; j <= maxv; j += i) vis[j] = true; } } void gao(int num) { int ans = 0; int msize = pnum.size(); for(int i = 0; i < msize; i++) { for(int j = i; j < msize && pnum[i] + pnum[j] < num; j++) { int tt = num - pnum[i] - pnum[j]; if(!vis[tt] && tt >= pnum[j]) ans++; if(tt < pnum[j]) break; } } printf("%d\n", ans); } int main() { init(); int n; while(scanf("%d", &n) != EOF) { gao(n); } return 0; }
B 直接求导之后找极值点就好了,注意特判a,b等于0的情况。
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; const double eps = 1e-9; int getx2p(double a, double b, double c, double &x1, double &x2) { double delta = b * b - 4 * a * c; if(delta < 0) return 0; x1 = -b + sqrt(delta); x2 = -b - sqrt(delta); x1 /= 2 * a; x2 /= 2 * a; if(delta < eps) return 1; else return 2; } bool inrange(double n, double L, double R) { L -= eps; R += eps; return (n >= L && n <= R); } double f(double x, double a, double b, double c, double d) { return a * x * x * x + b * x * x + c * x + d; } int main() { double a, b, c, d, L, R; while(scanf("%lf%lf%lf%lf%lf%lf", &a, &b, &c, &d, &L, &R) != EOF) { double p0, p1; int ret = getx2p(3 * a, 2 * b, c, p0, p1); double ans = -1e30; if(a == 0 && b == 0) { ans = max(abs(f(L, a, b, c, d)), abs(f(R, a, b, c, d))); } else if(a == 0) { ans = max(abs(f(L, a, b, c, d)), abs(f(R, a, b, c, d))); double mid = -c / (2 * b); if(inrange(mid, L, R)) { ans = max(ans, f(mid, a, b, c, d)); } } else if(ret == 0 || (!inrange(p0, L, R) && !inrange(p1, L, R))) { ans = max(abs(f(L, a, b, c, d)), abs(f(R, a, b, c, d))); } else { ans = max(abs(f(L, a, b, c, d)), abs(f(R, a, b, c, d))); if(inrange(p0, L , R)) ans = max(ans, abs(f(p0, a, b, c, d))); if(inrange(p1, L , R)) ans = max(ans, abs(f(p1, a, b, c, d))); } printf("%.2f\n", ans); } return 0; }
C 数位DP,思路和HDU 4507很像,也可以用排列组合直接搞。。
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> using namespace std; typedef long long LL; const int maxn = 1e3 + 100; const LL mod = 1e9 + 7; char buf[maxn]; int lim[maxn], n, len; LL p2[maxn]; bool vis[maxn][maxn]; struct EE { LL cnt, sum; EE(LL cnt = 0, LL sum = 0): cnt(cnt), sum(sum) {} }; EE f[maxn][maxn]; EE dfs(int now, int bitcnt, bool bound) { if(now == 0) return EE(bitcnt == 0, 0); if(vis[now][bitcnt] && !bound) return f[now][bitcnt]; int m = bound ? lim[now - 1] : 1; EE ret(0, 0); for(int i = 0; i <= m; i++) { EE nret = dfs(now - 1, bitcnt - i, bound && i == m); LL ff = p2[now - 1] * i % mod; ret.cnt = (ret.cnt + nret.cnt) % mod; ret.sum = ((nret.cnt * ff % mod + nret.sum) % mod + ret.sum) % mod; } if(!bound) { vis[now][bitcnt] = true; f[now][bitcnt] = ret; } return ret; } void gao() { len = strlen(buf); bool flag = false; for(int i = 0, j = len - 1; i < len; i++, j--) { lim[j] = buf[i] - '0'; } int pos; for(pos = 0; lim[pos] == 0; pos++) lim[pos] = 1; lim[pos] = 0; if(pos == len - 1) len--; EE ret = dfs(len, n, true); cout << ret.sum << endl; } void init() { p2[0] = 1; for(int i = 1; i <= 1000; i++) { p2[i] = (p2[i - 1] * 2) % mod; } } int main() { init(); while(scanf("%d%s", &n, buf) != EOF) { gao(); } return 0; }
D 线段树
先把所有的点按照y排序,然后在x轴上一个一个插入然后统计即可。
#include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; #define lson rt << 1, l, mid #define rson rt << 1 | 1, mid + 1, r const int maxn = 3e4 + 100; const int inf = 1e9 + 100; struct Node { int val[12]; Node() { for(int i = 1; i <= 11; i++) val[i] = inf; } void Megre(int val1[12]) { int tar[22]; for(int i = 1; i <= 10; i++) { tar[i] = val[i]; tar[i + 10] = val1[i]; } sort(tar + 1, tar + 21); for(int i = 1; i <= 10; i++) val[i] = tar[i]; val[11] = inf; } void Megre(int k) { val[11] = k; sort(val + 1, val + 12); val[11] = inf; } void print() { for(int i = 1; i <= 10; i++) { printf("%d ", val[i]); } puts(""); } }; Node minv[maxn << 4]; void pushup(int rt) { minv[rt] = minv[rt << 1]; minv[rt].Megre(minv[rt << 1 | 1].val); } void build(int rt, int l, int r) { if(l == r) minv[rt] = Node(); else { int mid = (l + r) >> 1; build(lson); build(rson); pushup(rt); } } void update(int rt, int l, int r, int pos, int x) { if(l == r) minv[rt].Megre(x); else { int mid = (l + r) >> 1; if(pos <= mid) update(lson, pos, x); else update(rson, pos, x); pushup(rt); } } Node query(int rt, int l, int r, int ql, int qr) { if(ql <= l && qr >= r) return minv[rt]; else { int mid = (l + r) >> 1; Node ret = Node(); if(ql <= mid) ret.Megre(query(lson, ql, qr).val); if(qr > mid) ret.Megre(query(rson, ql, qr).val); return ret; } } struct Point { int x, y, h, k; int id; bool isq; Point(int x, int y, int h, bool isq, int k = 0, int id = 0): x(x), y(y), h(h), isq(isq), k(k), id(id) {} bool operator < (const Point &p) const { if(y == p.y) return x < p.x; return y < p.y; } }; int n, m, ans[maxn]; vector<int> vnum; vector<Point> pp; int getid(int val) { int ret = lower_bound(vnum.begin(), vnum.end(), val) - vnum.begin() + 1; return ret; } int main() { while(scanf("%d%d", &n, &m) != EOF) { vnum.clear(); pp.clear(); for(int i = 1; i <= n; i++) { int x, y, h; scanf("%d%d%d",&x, &y, &h); pp.push_back(Point(x, y, h, false)); vnum.push_back(x); } for(int i = 1; i <= m; i++) { int x, y, k; scanf("%d%d%d", &x, &y, &k); pp.push_back(Point(x, y, 0, true, k, i)); vnum.push_back(x); } sort(vnum.begin(), vnum.end()); sort(pp.begin(), pp.end()); vnum.erase(unique(vnum.begin(), vnum.end()), vnum.end()); int mm = pp.size(), nn = vnum.size(); build(1, 1, nn); for(int i = 0; i < mm; i++) { if(pp[i].isq == false) { update(1, 1, nn, getid(pp[i].x), pp[i].h); } else { Node ret = query(1, 1, nn, 1, getid(pp[i].x)); ans[pp[i].id] = ret.val[pp[i].k]; } } for(int i = 1; i <= m; i++) { if(ans[i] == inf) ans[i] = -1; printf("%d\n", ans[i]); } } return 0; }