AtCoder Beginner Contest 218(补题)
Posted 佐鼬Jun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtCoder Beginner Contest 218(补题)相关的知识,希望对你有一定的参考价值。
C - Shapes
题意:
给定两个图, S S S和 T T T,’#'代表图案, ‘ . ’ ‘.’ ‘.’代表空,整幅图是 N ✖ N N✖N N✖N的大小,现在问你,能否旋转90°和平移的操作(操作数不限),来把S图中的图案,变成T中的图案
思路:
找到S图和T图中,图案的最左端、右端、上端、下端的坐标,上下左右坐标之外的地方说明都是空地,不用管,此时,此时,把新图(坐标是最左端右端上端下端之中的图),通过旋转,会有4种情况,旋转0,90,180,270,把旋转出来的图,存下来,看T图中是否有上述4种情况之一的图,可以小优化一下,如果找出来的图,一个是正方形另一个不是,那就直接不行。
#include <bits/stdc++.h>
using namespace std;
const int N = 210;
#define inf 0x3f3f3f3f
char S[N][N], T[N][N];
int n;
int u, l, r, d;
int U, L, R, D;
void change() {
map<string, int> m;
int f1, f2, f3, f4;
f1 = f2 = f3 = f4 = 1;
string s;
for (int i = u; i <= d; i++) {
for (int j = l; j <= r; j++) {
s.push_back(S[i][j]);
}
}
m[s]++;
s.clear();
for (int i = l; i <= r; i++) {
for (int j = d; j >= u; j--) {
s.push_back(S[j][i]);
}
}
m[s]++;
s.clear();
for (int i = r; i >= l; i--) {
for (int j = u; j <= d; j++) {
s.push_back(S[j][i]);
}
}
m[s]++;
s.clear();
for (int i = d; i >= u; i--) {
for (int j = r; j >= l; j--) {
s.push_back(S[i][j]);
}
}
m[s]++;
s.clear();
for (int i = U; i <= D; i++) {
for (int j = L; j <= R; j++) {
s.push_back(T[i][j]);
}
}
if (m[s] >= 1) {
puts("Yes");
} else
puts("No");
return;
}
int main() {
cin >> n;
u = U = l = L = inf;
r = d = R = D = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cin >> S[i][j];
if (S[i][j] == '#') {
u = min(u, i);
d = max(d, i);
l = min(l, j);
r = max(r, j);
}
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cin >> T[i][j];
if (T[i][j] == '#') {
U = min(U, i);
D = max(D, i);
L = min(L, j);
R = max(R, j);
}
}
}
//一方为正方形,另一方不是
if (d - u == R - l && r - l != D - U && r - l == R - L && d - u != D - U) {
puts("No");
return 0;
}
change();
return 0;
}
D - Rectangles
题意:
给 n n n个点的坐标,让你找四个坐标,组成一个矩形,问有多少个矩形的边与 x x x轴,或 y y y轴平行。
思路:
直接枚举矩形的右上端点(
x
1
,
y
1
x_1,y_1
x1,y1)和左下端点(
x
2
,
y
2
x_2,y_2
x2,y2),看是否右两个点的坐标(
x
1
,
y
2
x_1,y_2
x1,y2)(
x
2
,
y
1
x_2,y_1
x2,y1)来组成一个符合题意的矩形。
找(
x
1
,
y
2
x_1,y_2
x1,y2)(
x
2
,
y
1
x_2,y_1
x2,y1)这两个坐标的方法,可以用binary_search函数来二分找,也可以用桶提前把坐标存下来,来找。
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int N = 2020;
#define x first
#define y second
int n;
int main() {
scanf("%d", &n);
vector<PII> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i].x >> a[i].y;
}
sort(a.begin(), a.end());
int res = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (a[i].x < a[j].x && a[i].y < a[j].y) {
if (binary_search(a.begin(), a.end(),
make_pair(a[i].x, a[j].y)) &&
binary_search(a.begin(), a.end(),
make_pair(a[j].x, a[i].y))) {
res++;
}
}
}
}
printf("%d\\n", res);
return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
struct node {
int x, y;
} e[N];
map<int, map<int, int>> vis;
int n;
bool cmp(node a, node b) {
if (a.x != b.x) return a.x < b.x;
return a.y < b.y;
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> e[i].x >> e[i].y;
vis[e[i].x][e[i].y] = 1;
}
sort(e + 1, e + n + 1, cmp);
int res = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (e[i].x < e[j].x && e[i].y < e[j].y) {
if (vis[e[i].x][e[j].y] == 1 && vis[e[j].x][e[i].y] == 1) {
res++;
}
}
}
}
cout << res << endl;
}
E - Destruction
题意:
给你一张连通图, n n n个点 m m m条边,现在让你在满足图是连通的情况下,删除一些边w,如果删除的边是正的,你将会得到+w的价值,如果删除的边是负的,你将会得到-w的价值,现在让你删除一些边,并保证图是连通的,问你能得到的最大价值。
思路:
所有边的权值和 − - −最小生成树(这个不是严格的最小生成树,所有负数边全放在生成树边中)的边权和= a n s ans ans
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10, M = N * 2;
#define int long long
struct node {
int a, b;
int w;
bool operator<(const node &t) const { return w < t.w; }
} e[M];
int fa[N];
int n, m;
int find(int x) {
if (x != fa[x]) fa[x] = find(fa[x]);
return fa[x];
}
signed main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
fa[i] = i;
}
int sum = 0;
for (int i = 0; i < m; i++) {
int a, b, c;
scanf("%lld%lld%lld", &a, &b, &c);
e[i] = {a, b, c};
sum += c;
}
sort(e, e + m);
int res = 0;
for (int i = 0; i < m; i++) {
int a = e[i].a, b = e[i].b, c = e[i].w;
a = find(a), b = find(b);
if (a != b || (c < 0)) {
fa[a] = b;
res += c;
}
}
cout << sum - res << endl;
}
F - Blocked Roads
题意:
给你一个
n
n
n个点
以上是关于AtCoder Beginner Contest 218(补题)的主要内容,如果未能解决你的问题,请参考以下文章 AtCoder Beginner Contest 115 题解