A. Mishka and Game(Codeforces 703A)
思路
用兩個變量統計兩個人各勝了多少局,根據不同的的比較結果輸出不同的答案即可。
代碼
#include <bits/stdc++.h>
using namespace std;
int n, m, c, M, C;
int main() {
scanf("%d", &n);
for(int i = 0; i < n; i++) {
scanf("%d%d", &m, &c);
if(m > c) {
M++;
}
if(c > m) {
C++;
}
}
if(M == C) {
puts("Friendship is magic!^^");
}
else {
puts(M > C ? "Mishka" : "Chris");
}
return 0;
}
B. Mishka and trip(Codeforces 703B)
思路
首先將
我們可以用直接法或間接法來處理這個重複。對於直接法,我們可以在遍歷首都的同時維護已經處理過的首都的集合
代碼
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
int n, k, L, R, M;
ll oth, sum, ans, tmp, c[maxn];
set <int> s;
int main() {
scanf("%d%d", &n, &k);
for(int i = 1; i <= n; i++) {
scanf("%I64d", &c[i]);
sum += c[i];
if(i > 1) {
ans += c[i] * c[i-1];
}
}
ans += c[1] * c[n];
while(k--) {
scanf("%d", &M);
L = M == 1 ? n : M - 1;
R = M == n ? 1 : M + 1;
oth = sum - c[M] - tmp;
if(!s.count(L)) {
oth -= c[L];
}
if(!s.count(R)) {
oth -= c[R];
}
ans += c[M] * oth;
tmp += c[M];
s.insert(M);
}
printf("%I64d\n", ans);
return 0;
}
C. Chris and Road(Codeforces 703C)
思路
這道題看似十分複雜,但是巧妙地將問題轉化就能夠以非常優雅的方法順利解決。我們可以在時間確定的情況下以凸多邊形爲參考系,將
代碼
#include <bits/stdc++.h>
using namespace std;
struct Point {
double x, y;
Point() {}
Point(double x, double y): x(x), y(y) {}
void input() {
scanf("%lf%lf", &x, &y);
}
friend Point operator + (const Point& a, const Point& b) {
return Point(a.x + b.x, a.y + b.y);
}
};
const int maxn = 1e4 + 5;
const double eps = 1e-10;
int n;
double w, v, u, l, r, mid;
Point A, B, ps[maxn];
int cmp(double x) {
return x < -eps ? -1 : x > eps;
}
// 計算叉積
double det(Point a, Point b) {
return a.x * b.y - b.x * a.y;
}
// 判斷是否能夠直接通過
bool passDirectly() {
for(int i = 1; i <= n; i++) {
if(cmp(det(A, ps[i])) > 0) {
return false;
}
}
return true;
}
// 判斷在時刻t的時候是否能夠通過
bool ok(double t) {
for(int i = 1; i <= n; i++) {
B = ps[i] + Point(-v * t, 0);
if(cmp(det(A, B)) < 0) {
return false;
}
}
return true;
}
int main() {
scanf("%d%lf%lf%lf", &n, &w, &v, &u);
A = Point(v, u);
for(int i = 1; i <= n; i++) {
ps[i].input();
}
if(passDirectly()) {
printf("%.10f\n", 1.0 * w / u);
return 0;
}
l = 0;
r = 2e9;
// 二分查找
for(int i = 0; i < 100; i++) {
mid = (l + r) / 2;
ok(mid) ? r = mid : l = mid;
}
printf("%.10f\n", 1.0 * w / u + r);
return 0;
}
D. Mishka and Interesting sum(Codeforces 703D)
思路
由題目的“出現偶數次的數”,應該聯想到出現偶數次的數的異或和爲
代碼
#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) (x & -x)
struct query {
int l, r, idx;
query() {}
query(int l, int r, int idx): l(l), r(r), idx(idx) {}
bool operator < (const query& o) const {
return r < o.r;
}
};
const int maxn = 1e6 + 10, maxm = 1e6 + 10;
int n, m, l, r, idx, cur, a[maxn], c[maxn], xorSum[maxn], ans[maxm];
query qs[maxm];
map <int, int> mp;
void add(int p, int x) {
for(; p <= n; p += lowbit(p)) {
c[p] ^= x;
}
}
int sum(int p) {
int res = 0;
for(; p > 0; p -= lowbit(p)) {
res ^= c[p];
}
return res;
}
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
xorSum[i] = a[i] ^ xorSum[i-1];
}
scanf("%d", &m);
for(int i = 1; i <= m; i++) {
scanf("%d%d", &l, &r);
qs[i] = query(l, r, i);
}
sort(qs + 1, qs + m + 1);
cur = 1;
for(int i = 1; i <= m; i++) {
l = qs[i].l;
r = qs[i].r;
idx = qs[i].idx;
for(; cur <= r; cur++) {
if(mp[a[cur]] > 0) {
add(mp[a[cur]], a[cur]);
}
add(cur, a[cur]);
mp[a[cur]] = cur;
}
ans[idx] = xorSum[r] ^ xorSum[l - 1] ^ sum(r) ^ sum(l - 1);
}
for(int i = 1; i <= m; i++) {
printf("%d\n", ans[i]);
}
return 0;
}
(其它題目略)