Codeforces Round #812 (Div. 2)
作者:互联网
A
这竟然是我场上唯一一道没1A的题,蚌。
注意初值问题。
#include <cstdio>
#include <algorithm>
#include <cstring>
inline int min(const int x, const int y) {return x < y ? x : y;}
inline int max(const int x, const int y) {return x > y ? x : y;}
int a[10];
int main() {
int _;
scanf("%d", &_);
while (_ --) {
int n, mxx = 0, mnx = 0, mxy = 0, mny = 0;
scanf("%d", &n);
for (int i = 1; i <= n; ++ i) {
int x, y;
scanf("%d%d", &x, &y);
mxx = max(mxx, x), mnx = min(mnx, x), mxy = max(mxy, y), mny = min(mny, y);
}
printf("%d\n", max(0, mxy - mny) * 2 + max(0, mxx - mnx) * 2);
}
return 0;
}
B
和某年普及组铺设道路一样。
更简单的方法是,显然如果序列不是单峰的就是 NO,否则 YES。
#include <cstdio>
#include <algorithm>
#include <cstring>
inline int min(const int x, const int y) {return x < y ? x : y;}
inline int max(const int x, const int y) {return x > y ? x : y;}
int a[100005];
int main() {
int _;
scanf("%d", &_);
while (_ --) {
int n, mx = 0;
long long ans = 0;
scanf("%d", &n);
for (int i = 1; i <= n; ++ i) scanf("%d", a + i), mx = max(mx, a[i]);
for (int i = 2; i <= n; ++ i) if (a[i] > a[i - 1]) ans += a[i] - a[i - 1];
if (ans + a[1] <= mx) puts("YES");
else puts("NO");
}
return 0;
}
C
考虑一个 \(k\),构造出 \(n-1...k^2-n+1\)。
每次找到最大的 \(k\) 即可。
记得截至写完这道题我的排名还是垫底
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
inline int min(const int x, const int y) {return x < y ? x : y;}
inline int max(const int x, const int y) {return x > y ? x : y;}
int a[100005];
void solve(int n) {
if (n == 0) return;
int k = sqrt(2 * n - 2 + 0.5);
solve(k * k - (n - 1));
for (int i = n - 1; i >= k * k - (n - 1); -- i) printf("%d ", i);
}
int main() {
int _;
scanf("%d", &_);
while (_ --) {
int n;
scanf("%d", &n);
solve(n);
puts("");
}
return 0;
}
D
如果每一层都去问,那么整个询问过程就是一颗二叉树,太慢了。
由于交互次数上限和暴力次数只差一个常数,所以考虑乱搞出 \(k\) 叉树式的询问方式。
如果像四叉树那样询问,那么对于四个人 \(a,b,c,d\),\(a\) 要和 \(b\) 打,\(c\) 要和 \(d\) 打,两边的胜者还要打,我们的目标就是两次问出 \(a,b,c,d\) 中的胜者。
分类讨论一下不难发现确实只需要两次。首先询问 \(a,c\) 谁赢了。
- 平局。胜者在 \(b,d\) 中。
- \(a\) 获胜。胜者在 \(a,d\) 中。
- \(c\) 获胜。胜者在 \(b,c\) 中。
注意当 \(n\) 为奇数时要特判,否则询问次数会超限。
第一次做交互题竟然一遍过了
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
inline int min(const int x, const int y) {return x < y ? x : y;}
inline int max(const int x, const int y) {return x > y ? x : y;}
int check(int a, int b) {
printf("? %d %d\n", a, b);
fflush(stdout);
int x;
scanf("%d", &x);
return x;
}
int solve(int l, int r) {
if (l == r) return l;
int mid = l + r >> 1;
int lmid = l + mid >> 1, rmid = mid + 1 + r >> 1;
int a = solve(l, lmid), b = solve(lmid + 1, mid), c = solve(mid + 1, rmid), d = solve(rmid + 1, r);
int tmp = check(a, c);
if (tmp == 0) {
if (check(b, d) == 1) return b;
else return d;
} else if (tmp == 1) {
if (check(a, d) == 1) return a;
else return d;
} else {
if (check(c, b) == 1) return c;
else return b;
}
}
int main() {
int _;
scanf("%d", &_);
while (_ --) {
int n;
scanf("%d", &n);
if (n & 1) {
int a = solve(1, 1 << n - 1), b = solve((1 << n - 1) + 1, 1 << n);
if (check(a, b) == 1) printf("! %d\n", a), fflush(stdout);
else printf("! %d\n", b), fflush(stdout);
} else printf("! %d\n", solve(1, 1 << n)), fflush(stdout);
}
return 0;
}
E
不难发现 \(a_{i,j}\) 位置可以与 \(a_{j,i}\) 交换。
从前往后考虑每个格子,如果 \(a_{i,j} < a_{j,i}\),那么第 \(k=i\) 的操作和 \(k=j\) 的操作要么同时执行要么同时不执行。反之有且仅有一个执行。
这玩意儿维护的方法多了去了,并查集,dfs……
官方给的是一个比较简洁并查集的维护方式。
所以我为什么过了D就摆烂,要是把这题切了岂不上大分
#include <cstdio>
#include <numeric>
#include <algorithm>
int a[1005][1005], fa[2005];
int find(int x) {
if (x < 0) return -find(-x);
return fa[x] == x ? x : fa[x] = find(fa[x]);
}
inline void merge(int u, int v) {
u = find(u), v = find(v);
if (u != v && u != -v) u > 0 ? fa[u] = v : fa[-u] = -v;
}
int main() {
int _;
scanf("%d", &_);
while (_ --) {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; ++ i)
for (int j = 1; j <= n; ++ j) scanf("%d", &a[i][j]);
std::iota(fa + 1, fa + 2 * n + 1, 1);
for (int i = 1; i <= n; ++ i)
for (int j = 1; j <= n; ++ j)
if (a[i][j] < a[j][i]) merge(i, j);
else if (a[i][j] > a[j][i]) merge(i, -j);
for (int i = 1; i <= n; ++ i) if (find(i) > 0)
for (int j = 1; j <= n; ++ j) std::swap(a[i][j], a[j][i]);
for (int i = 1; i <= n; ++ i, puts(""))
for (int j = 1; j <= n; ++ j) printf("%d ", a[i][j]);
}
return 0;
}
标签:return,int,scanf,Codeforces,solve,const,812,include,Div 来源: https://www.cnblogs.com/stinger/p/16558929.html