2018CCPC吉林赛区
A
分块, 签到
int main() {
IOS; int cas = 0;
for (cin >> _; _; --_) {
cin >> n; __int128 cur = 0;
for (int i = 1, j; i <= n; i = j + 1) {
j = min(n, n / (n / i));
cur += (__int128)n / i * (j - i + 1);
}
cout << "Case " << ++cas << ": ";
if (cur & 1) cout << "odd\n";
else cout << "even\n";
}
return 0;
}
B
模拟
int main() {
int cas = 0;
for (scanf("%d", &_); _; --_) {
int a, b; scanf("%d:%d %s", &a, &b, s + 1);
if (s[1] == 'A' && a == 12) a = 0;
else if (s[1] == 'P' && a != 12) a += 12;
scanf("%s%s", x + 1, y + 1);
if (x[1] == 'B') a = a - 8;
else if (x[1] == 'W') a = a + 5;
else if (x[1] == 'M') a = a - 3;
if (y[1] == 'B') a += 8;
else if (y[1] == 'W') a -= 5;
else if (y[1] == 'M') a += 3;
cout << "Case " << ++cas << ": ";
if (a >= 24) cout << "Tomorrow ";
else if (a < 0) cout << "Yesterday ";
else cout << "Today ";
a = (a + 24) % 24;
char c, d;
if (b < 10) c = '0';
else c = '0' + b / 10;
d = '0' + b % 10;
if (a == 0 || a == 24) cout << "12:" << c << d << " AM\n";
else if (a < 12) cout << a << ":" << c << d << " AM\n";
else if (a == 12) cout << "12:" << c << d << " PM\n";
else cout << a - 12 << ':' << c << d << " PM\n";
}
return 0;
}
C
不断合并就完事
int n, m, _, k;
int f[N], a[N];
int find(int x) {
return x == f[x] ? x : f[x] = find(f[x]);
}
void unit(int x, int y) {
x = find(x), y = find(y);
if (x == y) return;
f[y] = x;
}
int main() {
IOS; int cas = 0;
for (cin >> _; _; --_) {
cin >> n; unordered_map<int, int> st;
int x = 0, y = 0;
rep (i, 1, n) {
cin >> m, f[i] = i;
while (st[m]) unit(i, st[m]), st[m--] = 0;
if (m == 1) {
if (x == 0) x = i;
else if (y == 0) y = i;
}
else st[m] = i;
}
cout << "Case " << ++cas << ": ";
if (x == 0 || y == 0) cout << "NO\n";
else {
cout << "YES\n";
rep (i, 1, n) cout << (find(i) == x);
cout << '\n';
}
}
return 0;
}
D
正解没写出来, 不过我dp倒是写出来了, 不过跑 1~100超时, 大概5~7s
但是是 1~100 呦~, 打表啊~
打表的dp(输入100就行)
int n, m, _, k;
ll c[4005][4005];
long double p, q, f[4005] = {1};
void init(int n) {
rep (i, 0, n) c[i][0] = 1;
rep (i, 1, n) rep (j, 1, i) c[i][j] = c[i - 1][j - 1] + c[i - 1][j];
}
int main() {
IOS; int cas = 0; init(4000);
for (cin >> _; _; --_) {
p = (100 - _ + 1) / 100.0;
long double res = p * 0.02;
rep (i, 0, 4000) f[i] = 0; f[1] = 1;
rep (i, 1, 4000) {
per (j, i, 0) {
if (j) f[j] = f[j] * (1 - p) + f[j - 1] * p * (1 - min(j * 0.005 + 0.015 * i, 1.0));
else f[j] = f[j] * (1 - p);
res += f[j] * p * min(1.0, 0.005 * j + 0.015 * i + 0.02) * (i + 1);
}
}
cout << setiosflags(ios::fixed) << setprecision(12) << res << ',' << '\n';
}
return 0;
}
表就自己打吧, 不贴了, 主要是暴力一直跑不出来, 没办法写了dp, 结果还不是正解, 鬼知道是公式啊, 反正打表也相当快(5~7s),单询问绝不会超时
E
设碰撞点为 \((x_1, y_1, z_1)\), 则
\(\left\{\begin{matrix}x_1=x_0+v_x*t\\y_1=y_0+v_y*t\\z_1=z_0+v_z*t\end{matrix}\right.\)
考虑个相似三角形
$ \frac{\sqrt{x2+y2}}{r} = \frac {h-z_1}{h} $
拆开方, 带入原数, 得
\((v_x^2+v_y^2-\frac{r^2}{h^2}v_z^2)t^2+2(x*v_x+y*v_y-(z-h)\frac{r^2}{h^2}v_z)t=\frac{r^2}{h^2}*(h-z)^2-x^2-y^2\)
即 \(at^2+2bt=c\)
解为 \(t=\frac{\pm \sqrt {b^2+ac}-b}{a}\)
然后就是判两个解那个是实根且能在最短时间碰到圆锥
double r, h, x, y, z, vx, vy, vz;
bool check(double t) {
double a = x + vx * t, b = y + vy * t, c = z + vz * t;
return fabs(sqrt(sqr(a) + sqr(b)) * h - (h - c) * r) < 1e-8;
}
int main() {
IOS; int cas = 0;
for (cin >> _; _; --_) {
cin >> r >> h >> x >> y >> z >> vx >> vy >> vz;
double a = sqr(vx) + sqr(vy) - sqr(r / h * vz);
double b = x * vx + y * vy - sqr(r / h) * (z - h) * vz;
double c = sqr(r / h * (h - z)) - sqr(x) - sqr(y);
double der = sqrt(sqr(b) + a * c), t1 = (der - b) / a, t2 = (-der - b) / a;
double t = 2e18;
if (check(t1)) umin(t, t1);
if (check(t2)) umin(t, t2);
cout << "Case " << ++cas << ": " << setiosflags(ios::fixed) << setprecision(12) << t << '\n';
}
return 0;
}
F
签到题
int main() {
IOS; int cas = 0;
for (cin >> _; _; --_) {
cin >> n; int ans = 0;
rep (i, 1, n) {
int r; cin >> r;
if (r > 2) ans ^= r - 2;
}
cout << "Case " << ++cas << ": " << ans << '\n';
}
return 0;
}
I
大模拟
PII a[N], b[N];
ll solve(bool f) {
ll ans = 0; int i, j;
for (i = 1, j = n; j && i <= m; ++i, --j) {
if (a[j].se) { --i; continue; }
if (b[i].se) { ++j; continue; }
if (b[i].fi >= a[j].fi) return ans;
ans += a[j].fi - b[i].fi;
}
if (f) while (j) if (!a[j--].se) ans += a[j + 1].fi;
return ans;
}
int main() {
IOS; int cas = 0;
for (cin >> _; _; --_) {
cin >> n >> m;
rep (i, 1, n) cin >> a[i].fi, a[i].se = 0;
rep (i, 1, m) cin >> b[i].fi;
rep (i, 1, m) cin >> b[i].se;
sort(a + 1, a + 1 + n); sort(b + 1, b + 1 + m);
ll ans = solve(0);
bool f = 1;
for (int i = 1; i <= m && f; ++i)
if (b[i].se) {
int c = lower_bound(a + 1, a + 1 + n, PII{ b[i].fi, 0 }) - a;
while (c <= n && a[c].se) ++c;
if (c > n) f = 0;
a[c].se = 1;
}
if (f) ans = max(ans, solve(1));
cout << "Case " << ++cas << ": " << ans << '\n';
}
return 0;
}