Codeforces Round 886 (Div. 4)F~H
Codeforces Round 886 (Div. 4)F~H
F. We Were Both Children(枚举)
题意
有一堆青蛙,每次会跳ai步,最多跳到n,然后想知道在1~n里面,哪个点青蛙落地的次数最多
思路
先给ai相同的青蛙计数一下,map<int,int>w,表示有w[i]个青蛙的步数都是ai
然后枚举所有不同ai下,会在在1~n里,哪里落地,用cnt[]来计数,计数的时候注意权值w
看哪个点cnt最大就行
代码
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
vector<long long>ans;
map<int, int>vis, w, cnt;
vector<int>a;
void solve() {
w.clear();
vis.clear();
cnt.clear();
int n; cin >> n;
a.clear(); a.resize(n + 1);
for (int i = 1; i <= n; i++) {
cin >> a[i];
w[a[i]]++;
}
int res = 0;
for (int i = 1; i <= n; i++) {
if (vis[a[i]])continue;
vis[a[i]]++;
for (int k = 1; a[i] * k <= n; k++) {
cnt[a[i] * k] += w[a[i]];
res = max(res, cnt[a[i] * k]);
}
}
ans.push_back(res);
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int _; _ = 1;
cin >> _;
while (_--) solve();
for (auto x : ans)cout << x << endl;
return 0;
}
// 1 2 3 4 5
// 1 1 1 1 1
// 1 2 1 2 1
// 1 2 2 2 1
// 1 2 2 3 1
// 1 2 2 3 2
G. The Morning Star(数学)
题意
给一堆点,取两个点要在同一条直线上(有四条直线,不分方向)
思路
如果点a和点b在同一条直线上,他们的坐标有什么关系?
xa,ya,xb,yb
xa==xb || ya=yb(此时形成的线要么平行于x轴,要么垂直于x轴)
斜的,斜率为1或者-1
yb-ya == xb-xaxa+ya == xb+yb

代码
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
vector<long long>ans;
void solve() {
map<int, int>x, y, xy1, xy2;
set<int>sx, sy, sxy1, sxy2;
int n; cin >> n;
for (int i = 1, a, b; i <= n; i++) {
cin >> a >> b;
x[a]++;
y[b]++;
xy1[a + b]++;
xy2[a - b]++;
sx.insert(a);
sy.insert(b);
sxy1.insert(a + b);
sxy2.insert(a - b);
}
long long res = 0;
for (auto num : sx) {
res += x[num] * (x[num] - 1);
}
for (auto num : sy) {
res += y[num] * (y[num] - 1);
}
for (auto num : sxy1) {
res += xy1[num] * (xy1[num] - 1);
}
for (auto num : sxy2) {
res += xy2[num] * (xy2[num] - 1);
}
ans.push_back(res);
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int _; _ = 1;
cin >> _;
while (_--) solve();
for (auto x : ans)cout << x << endl;
return 0;
}
/*
星和指南针在同一条线上
如果点a和点b在同一条直线上,他们的坐标有什么关系?
xa,ya,xb,yb
xa==xb || ya=yb
斜的,斜率为1或者-1
yb-ya == xb-xa
xa+ya == xb+yb
yb-ya/xb-xa = 1/-1
*/
H. The Third Letter(带权并查集)
题意
给一堆条件,a,b,d说明b在a前面d米(d是负的话就是a后面|d|米)
思路
带权并查集
定义dis[i]表示节点i到它的父节点的距离(不是根节点)
-
find
int find(int x) {
if (par[x] == x)return x;
else {
int parX = find(par[x]); dis[x] += dis[par[x]];
par[x] = parX;
return par[x];
}
}

-
merge
void merge(int x, int y, int val) {
int parX = find(x);
int parY = find(y);
//if (parX == parY)return;
par[parY] = parX;
dis[parY] = dis[x] - val - dis[y];
}

边并查集边看看有没有矛盾就行
代码
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
vector<long long>ans;
const int N = 2e5 + 5;
int par[N], dis[N];
int find(int x) {
if (par[x] == x)return x;
else {
int parX = find(par[x]);
dis[x] += dis[par[x]];
par[x] = parX;
return par[x];
}
}
void merge(int x, int y, int val) {
int parX = find(x);
int parY = find(y);
//if (parX == parY)return;
par[parY] = parX;
dis[parY] = -dis[y] - val + dis[x];
}
void solve() {
int n, m; cin >> n >> m;
memset(dis, 0, sizeof(dis));
for (int i = 1; i <= n; i++) {
par[i] = i;
}
bool flag = false;
for (int i = 0, a, b, d; i < m; i++) {
cin >> a >> b >> d;
if (flag)continue;
if (find(a) != find(b)) {
merge(a, b, d);
}
else {
if (dis[a] - dis[b] != d) {
flag = true;
}
}
}
if (flag)cout << "NO" << endl;
else cout << "YES" << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int _; _ = 1;
cin >> _;
while (_--) solve();
for (auto x : ans)cout << x << endl;
return 0;
}

浙公网安备 33010602011771号