Xu Xiake in Henan Province
模拟。
#include <bits/stdc++.h>
using namespace std;
int main() {
#ifdef wxh010910
freopen("input.txt", "r", stdin);
#endif
int tt;
scanf("%d", &tt);
while (tt--) {
int total = 0;
for (int i = 0; i < 4; ++i) {
int x;
scanf("%d", &x);
if (x) {
++total;
}
}
switch (total) {
case 0:
puts("Typically Otaku");
break;
case 1:
puts("Eye-opener");
break;
case 2:
puts("Young Traveller");
break;
case 3:
puts("Excellent Traveller");
break;
case 4:
puts("Contemporary Xu Xiake");
break;
}
}
return 0;
}
Ultraman vs. Aodzilla and Bodzilla
贪心,记 f ( x ) f(x) f(x) 表示造成 x x x 点伤害需要的时间,那么有两种方案:
- 共打 f ( H P A + H P B ) f(HP_A + HP_B) f(HPA+HPB) 轮,在第 f ( H P A ) f(HP_A) f(HPA) 轮时打败 A A A 。
- 共打 f ( H P A + H P B ) f(HP_A + HP_B) f(HPA+HPB) 轮,在第 f ( H P B ) f(HP_B) f(HPB) 轮时打败 B B B 。
输出方案贪心即可。
#include <bits/stdc++.h>
using namespace std;
int main() {
#ifdef wxh010910
freopen("input.txt", "r", stdin);
#endif
int tt;
scanf("%d", &tt);
while (tt--) {
int hp_a, hp_b, attack_a, attack_b;
scanf("%d %d %d %d", &hp_a, &hp_b, &attack_a, &attack_b);
auto get_sum = [&](int x) {
return (long long)x * (x + 1) >> 1;
};
auto get_round = [&](int x) {
int result = 1;
while (get_sum(result) < x) {
++result;
}
return result;
};
int round_a = get_round(hp_a), round_b = get_round(hp_b), round_total = get_round(hp_a + hp_b);
long long answer = min((long long)attack_a * round_a + (long long)attack_b * round_total, (long long)attack_a * round_total + (long long)attack_b * round_b);
string result(round_total, 'B');
if ((long long)attack_a * round_a + (long long)attack_b * round_total == answer) {
string current(round_total, 'A');
for (int i = round_a; i < round_total; ++i) {
current[i] = 'B';
}
if (get_sum(round_a) - hp_a > get_sum(round_total) - hp_a - hp_b) {
current[get_sum(round_a) - hp_a - 1] = 'B';
}
result = min(result, current);
}
if ((long long)attack_a * round_total + (long long)attack_b * round_b == answer) {
string current(round_total, 'B');
for (int i = round_b; i < round_total; ++i) {
current[i] = 'A';
}
long long remain_b = get_sum(round_b) - hp_b, remain_a = remain_b - (get_sum(round_total) - hp_a - hp_b);
int last = -1;
for (int i = 0; i < round_a; ++i) {
if (remain_b >= i + 1) {
last = i;
current[i] = 'A';
remain_b -= i + 1;
remain_a -= i + 1;
}
}
if (remain_a > 0) {
current[last] = 'B';
current[last + remain_a] = 'A';
}
result = min(result, current);
}
cout << answer << " " << result << endl;
}
return 0;
}
Supreme Command
考虑坐标时,显然两维独立。考虑一个点的位置,可以表示成 max ( l , min ( x , r ) ) + d \max(l, \min(x,r)) + d max(l,min(x,r))+d 的形式,可以快速维护。
再考虑第二问,不难发现棋盘可以用两条横线两条竖线划分成 9 9 9 部分,因为初始每行每列只有一个车,所以只有 4 4 4 个角的车会占领重复位置。在操作时移动分界线即可。
#include <bits/stdc++.h>
using namespace std;
int main() {
#ifdef wxh010910
freopen("input.txt", "r", stdin);
#endif
ios::sync_with_stdio(0);
cin.tie(0);
int tt;
cin >> tt;
while (tt--) {
int n, m;
cin >> n >> m;
vector<int> x(n), y(n);
vector<int> px(n), py(n);
for (int i = 0; i < n; ++i) {
cin >> x[i] >> y[i];
--x[i];
--y[i];
px[x[i]] = i;
py[y[i]] = i;
}
int lx = 0, rx = n - 1, dx = 0;
int ly = 0, ry = n - 1, dy = 0;
int llx = -1, rrx = n;
int lly = -1, rry = n;
int ul = 0, ur = 0, dl = 0, dr = 0;
while (m--) {
string type;
cin >> type;
if (type == "U") {
int shift;
cin >> shift;
int low = max(lx + dx - shift, 0);
int high = max(rx + dx - shift, 0);
if (low == high) {
lx = rx = 0;
} else {
lx = rx - high + low;
}
dx = high - rx;
} else if (type == "D") {
int shift;
cin >> shift;
int low = min(lx + dx + shift, n - 1);
int high = min(rx + dx + shift, n - 1);
if (low == high) {
lx = rx = 0;
} else {
rx = lx + high - low;
}
dx = low - lx;
} else if (type == "L") {
int shift;
cin >> shift;
int low = max(ly + dy - shift, 0);
int high = max(ry + dy - shift, 0);
if (low == high) {
ly = ry = 0;
} else {
ly = ry - high + low;
}
dy = high - ry;
} else if (type == "R") {
int shift;
cin >> shift;
int low = min(ly + dy + shift, n - 1);
int high = min(ry + dy + shift, n - 1);
if (low == high) {
ly = ry = 0;
} else {
ry = ly + high - low;
}
dy = low - ly;
} else if (type == "?") {
int id;
cin >> id;
--id;
printf("%d %d\n", max(lx, min(rx, x[id])) + dx + 1, max(ly, min(ry, y[id])) + dy + 1);
} else if (type == "!") {
auto get = [&](int x) {
return (long long)x * (x - 1) >> 1;
};
long long answer = 0;
if (lx == rx && ly == ry) {
printf("%lld\n", get(n));
} else if (lx == rx) {
printf("%lld\n", get(ly + 1) + get(n - ry));
} else if (ly == ry) {
printf("%lld\n", get(lx + 1) + get(n - rx));
} else {
while (llx < lx) {
++llx;
int id = px[llx];
if (y[id] <= lly) {
++ul;
}
if (y[id] >= rry) {
++ur;
}
}
while (rrx > rx) {
--rrx;
int id = px[rrx];
if (y[id] <= lly) {
++dl;
}
if (y[id] >= rry) {
++dr;
}
}
while (lly < ly) {
++lly;
int id = py[lly];
if (x[id] <= llx) {
++ul;
}
if (x[id] >= rrx) {
++dl;
}
}
while (rry > ry) {
--rry;
int id = py[rry];
if (x[id] <= llx) {
++ur;
}
if (x[id] >= rrx) {
++dr;
}
}
printf("%lld\n", get(ul) + get(ur) + get(dl) + get(dr));
}
}
}
}
return 0;
}
Keiichi Tsuchiya the Drift King
分是否取到最大值两种情况讨论一下。
#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1);
int main() {
#ifdef wxh010910
freopen("input.txt", "r", stdin);
#endif
int tt;
scanf("%d", &tt);
while (tt--) {
int a, b, r, d;
scanf("%d %d %d %d", &a, &b, &r, &d);
double angle = d * pi / 180;
if (angle >= atan((double)b / (a + r))) {
printf("%.9lf\n", sqrt(b * b + (a + r) * (a + r)) - r);
} else {
printf("%.9lf\n", (r + a) * cos(angle) + b * sin(angle) - r);
}
}
return 0;
}
Resistors in Parallel
考虑最后选择了 ∏ i = 1 k p i \prod_{i=1}^k p_i ∏i=1kpi ,那么其贡献是 ∏ i = 1 k p i + 1 p i \prod_{i=1}^k \frac{p_i+1}{p_i} ∏i=1kpipi+1 ,选前若干小的质数即可。
def gcd(x, y):
if y:
return gcd(y, x % y)
return x
tt = int(raw_input<