ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Codeforces Round #812 (Div. 2)

2022-08-07 13:30:23  阅读:128  来源: 互联网

标签:return int scanf Codeforces solve const 812 include Div


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\) 谁赢了。

  1. 平局。胜者在 \(b,d\) 中。
  2. \(a\) 获胜。胜者在 \(a,d\) 中。
  3. \(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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有