Loading

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

想补

posted @ 2022-07-11 16:22  dgsvygd  阅读(24)  评论(0编辑  收藏  举报