AtCoder Beginner Contest 259 A - E
A - Growth Record
看题直接算,就出生之后 X 岁以下的身高增速为 D,给出 N 岁时身高为 T,求 M 岁时身高是多少
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
#include <array>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
int main()
{
int n, m, x, t, d;
scanf("%d%d%d%d%d", &n, &m, &x, &t, &d);
int ans = t;
for(int i=n; i<m; i++)
{
if(i < x) ans += d;
}
for(int i=n; i>m; i--)
{
if(i <= x) ans -= d;
}
printf("%d\n", ans);
return 0;
}
B - Counterclockwise Rotation
点 \((x_1, y_1)\) 绕点 \((x_2,y_2)\) 逆时针旋转 \(\alpha\) 度,得到点 \((x_0, y_0)\)
\(x_0 = (x_1 - x_2) * cos(\alpha) - (y1 - y2) * sin(\alpha) + x_2\)
\(y_0 = (y_1 - y_2) * cos(\alpha) + (x_1 - x_2) * sin(\alpha) + y_2\)
记得代码里的 \(\alpha\) 是弧度制:\(\alpha = \frac{\theta}{180} * \pi\)
越来越觉得自己是个数学废人了,高中时期或许是我的数学巅峰时期
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
#include <array>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
const double pi = acos(-1.0);
int main()
{
double x, y, d;
scanf("%lf%lf%lf", &x, &y, &d);
d = (d / 180 * pi);
double ax = x * cos(d) - y * sin(d);
double ay = y * cos(d) + x * sin(d);
printf("%.10lf %.10lf\n", ax, ay);
return 0;
}
C - XX to XXX
类似于离散化,合并以下当前相同字母区间出现的字母次数,然后分类讨论下就行
我又双叒叕读错题了,以为中间添加的能是不同字母,原来只能添加和左右两边相同的字母
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
#include <array>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
const double pi = acos(-1.0);
int vis[maxn];
int main()
{
string s, t;
cin >> s >> t;
int tp = 0, tt = 0;
char ch = 0;
int f = 1;
while(tp < s.length() && tt < t.length() && f)
{
int ta = 0, tb = 0;
ch = s[tp];
while(tp < s.length() && ch == s[tp])
{
ta++;
tp++;
}
while(tt < t.length())
{
if(ch != t[tt]) break;
tb++;
tt++;
}
if(ta > tb) f = 0;
else if(ta == 1 && ta != tb) f = 0;
}
if(tt != t.length() || tp != s.length()) f = 0;
if(f) cout << "Yes" << endl;
else cout << "No" << endl;
return 0;
}
D - Circumferences
并查集
找到点所在的两个圆,然后将所有的圆互相判断一下是否相交,如果相交则并查集连起来,注意同心圆的情况
最后判断所在的两个圆是否连通
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
#include <array>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 3010;
const ll inf = 1e17 + 10;
const double pi = acos(-1.0);
int top[maxn];
struct node
{
ll x, y, r;
}p[maxn];
ll dis(node a, node b)
{
ll xx = a.x - b.x;
ll yy = a.y - b.y;
return xx * xx + yy * yy;
}
int query(int x)
{
return x == top[x] ? x : top[x] = query(top[x]);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
ll sx, sy, ex, ey;
int n;
cin >> n >> sx >> sy >> ex >> ey;
for(int i=0; i<n; i++) top[i] = i;
int f = 0;
int sa = 0, sb = 0;
for(int i=0; i<n; i++)
{
ll a, b, c;
cin >> a >> b >> c;
p[i] = {a, b, c};
int temp = 0;
if(dis(p[i], node{sx, sy, 0}) == p[i].r * p[i].r)
sa = i;
if(dis(p[i], {ex, ey, 0}) == p[i].r * p[i].r)
sb = i;
}
for(int i=0; i<n; i++)
{
for(int j=i+1; j<n; j++)
{
if(dis(p[i], p[j]) <= (p[i].r + p[j].r) * (p[i].r + p[j].r))
{
if(p[i].x == p[j].x && p[i].y == p[j].y && p[i].r != p[j].r) continue;
int a = query(i), b = query(j);
if(a != b)
{
top[a] = b;
}
}
}
}
if(query(sa) == query(sb)) f = 1;
if(f) cout << "Yes" << endl;
else cout << "No" << endl;
return 0;
}
E - LCM on Whiteboard
LCM 要产生变化的话主要是看因数分解之后,所有素数最高次有没有发生改变
因此我们要记录一下所有出现过的素数的最高次和次高次,接着遍历每一种组合,如果缺失了的话,判断一下会不会对最高次造成影响
因为会有不同的数字对最高次造成影响,因此我考虑的是将造成影响的最高次记录下来,然后判重
一开始觉得 set<vector<int> >
判重的方式特别莽,但是后来发现总共也就出现 \(2e^5\) 个素数,因此能过也合情合理
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
#include <array>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
const double pi = acos(-1.0);
vector<pii>p[maxn];
map<int, int>mp;
int fa[maxn], fb[maxn];
int tp = 0;
int main()
{
int n;
scanf("%d", &n);
for(int i=0; i<n; i++)
{
int m;
scanf("%d", &m);
for(int j=0; j<m; j++)
{
int a, b;
scanf("%d%d", &a, &b);
p[i].push_back({a, b});
if(mp.count(a) == 0) mp[a] = ++tp;
int now = mp[a];
if(b > fa[now]) {swap(fa[now], fb[now]); fa[now] = b;}
else if(b > fb[now]) fb[now] = b;
}
}
set<vector<int> >s;
for(int i=0; i<n; i++)
{
vector<int>now;
for(auto [a, b] : p[i])
{
int x = mp[a];
if(fa[x] == fb[x]) continue;
if(fa[x] == b) now.push_back(a);
}
s.insert(now);
}
printf("%d\n", s.size());
return 0;
}
赛后参照队友的,写了一个不用 set
判重的,因为每个素数被松弛至多只有一次
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
#include <array>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
const double pi = acos(-1.0);
vector<pii>p[maxn];
map<int, int>mp;
int fa[maxn], fb[maxn], vis[maxn];
int tp = 0;
int main()
{
int n;
scanf("%d", &n);
for(int i=0; i<n; i++)
{
int m;
scanf("%d", &m);
for(int j=0; j<m; j++)
{
int a, b;
scanf("%d%d", &a, &b);
p[i].push_back({a, b});
if(mp.count(a) == 0) mp[a] = ++tp;
int now = mp[a];
if(b > fa[now]) {swap(fa[now], fb[now]); fa[now] = b;}
else if(b > fb[now]) fb[now] = b;
}
}
int ans = 0, flag = 0;
for(int i=0; i<n; i++)
{
int f = 0;
for(auto [a, c] : p[i])
{
int nex = mp[a];
if(fa[nex] != fb[nex] && vis[nex] == 0 && c == fa[nex]) f = 1;
if(c == fa[nex])
vis[nex] = 1;
}
if(f) ans += f;
else if(flag == 0)
{
flag = 1;
ans++;
}
}
printf("%d\n", ans);
return 0;
}
F - Select Edges
想补