2013 南京市邀请赛 A,C,H, K
2013 南京邀请赛 A,C,H, K
C:
H:
K:
A题:求期望,先统计出每次得分期望,然后如果获得再一次机会,下次期望为n / m * 期望,n为总个数,m为在一次的个数,然后利用等比数列前
n项和的公式去算即可,要注意特判一下可能出现inf的情况,即期望不为0,且n / m = 1。
C题:a,b范围内,把每个数字拆成32位,计算0-a每位多少个1,0-b每位多少个1,相减后在去计算总进位次数即可
H题:签到题,找出重复数字。
K题:数论,求是否存在ID % X1 属于[Y1,Z1] && ID % X2 属于[Y2, Z2], 设ID % X1 = u, ID % X2 = v, ID / X1 = a, ID / X2 = b; 那么Id - x1 * a = u, id - x2 * b = v;
x2 * b - x1 * a = u - v; 这样就变成了a * x + b *y = c判断有无整数解,欧几里德定理,只要c是gcd(a,b)的整数倍即可。
那么t = gcd(x1, x2), u - v的范围可以求出来为[y1 - z2, z1 - y2],然后判断一下是不是整数倍即可
代码:
A:
#include <cstdio> #include <cstring> #include <cmath> const double esp = 1e-9; const int N = 205; int n, m, tmp, vis[N]; double num, sum, mm; int main() { while (~scanf("%d", &n)) { sum = 0; mm = 0; memset(vis, 0, sizeof(vis)); for (int i = 0; i < n; i++) { scanf("%lf", &num); sum += num; } sum /= n; scanf("%d", &m); while (m--) { scanf("%d", &tmp); if (!vis[tmp]) mm++; vis[tmp] = 1; } mm /= n; if (fabs(sum) < esp) printf("0.00\n"); else if (fabs(sum) >= esp && fabs(mm - 1) < esp) printf("inf\n"); else printf("%.2lf\n", sum / (1 - mm)); } return 0; }
C:
#include <cstdio> #include <cstring> #include <iostream> using namespace std; const int N = 35; long long a, b; long long d1[N], d2[N], mi[N]; void init() { mi[0] = 1; for (int i = 1; i <= 32; i++) mi[i] = mi[i - 1] * 2; } void build(long long *d, long long num) { for (int i = 0; i < 32; i++) { long long c = num / mi[i + 1]; long long yu = num % mi[i + 1] - mi[i]; if (yu < 0) yu = 0; d[i] = c * mi[i] + yu; } } int main() { init(); while (cin >> a >> b) { memset(d1, 0, sizeof(d1)); memset(d2, 0, sizeof(d2)); build(d1, a); build(d2, b + 1); for (int i = 0; i < 32; i++) d2[i] -= d1[i]; long long s = 0, ans = 0; for (int i = 0; i < 32; i++) { s = (d2[i] + s) / 2; ans += s; } while (s) { s /= 2; ans += s; } cout << ans << endl; } return 0; }
H:
#include <stdio.h> #include <string.h> const int N = 1005; int n, num, vis[N]; int main() { while (~scanf("%d", &n)) { memset(vis, 0, sizeof(vis)); for (int i = 0; i <= n; i++) { scanf("%d", &num); vis[num]++; if (vis[num] == 2) printf("%d\n", num); } } return 0; }
K:
#include <stdio.h> #include <string.h> const int N = 1005; int n, x[N], y[N], z[N]; int gcd(int a, int b) { if (b == 0) return a; return gcd(b, a % b); } bool judge(int t, int l, int r) { if (l % t == 0 || r % t == 0) return true; if (l < 0 && r >= 0) return true; if (r / t - l / t > 0) return true; return false; } bool solve() { for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { int t = gcd(x[i], x[j]); if (judge(t, y[i] - z[j], z[i] - y[j])) return true; } } return false; } int main() { while (~scanf("%d", &n)) { for (int i = 0; i < n; i++) scanf("%d%d%d", &x[i], &y[i], &z[i]); if (solve()) printf("Cannot Take off\n"); else printf("Can Take off\n"); } return 0; }