• AtCoder Beginner Contest 168


    传送门

    A - ∴ (Therefore)

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    int main() {
        int n;
        scanf("%d", &n), n %= 10;
        if(n == 2 || n == 4 || n == 5 || n == 7 || n == 9) printf("hon
    ");
        else if(n == 0 || n == 1 || n == 6 || n == 8) printf("pon
    ");
        else printf("bon
    ");
        return 0;
    }
    A.cpp

    B - ... (Triple Dots)

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    char s[105];
    int main() {
        int k;
        scanf("%d%s", &k, s);
        int n = strlen(s);
        if(n > k) {
            for(int i = 0; i < k; i++) {
                printf("%c", s[i]);
            }
            printf("...
    ");
        }else {
            printf("%s
    ", s);
        }
        return 0;
    }
    B.cpp

    C - : (Colon)

    题意:给定时钟的时针,分针长度A,B,以及当前的时间H:M,求时针分针顶部之间的距离。

    数据范围:$ 1 leq A,B leq 1000, 0 leq H leq 11, 0 leq M leq 59 $

    题解:求出时针分针之间的角度,然后用余弦定理算出距离。

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const double PI = acos(-1.0);
    int main() {
        int a, b, h, w;
        scanf("%d%d%d%d", &a, &b, &h, &w);
        double d = fabs(30 * h - 5.5 * w);
        printf("%.12f
    ", sqrt(a * a + b * b - 2 * cos(d / 180 * PI) * a * b));
        return 0;
    }
    C.cpp

    D - .. (Double Dots)

    题意:给一个N个点的图,M条边,在每个点设一个路标,每次只能向路标的点走,求一种方案最小化每个点到1的距离,若有点到不了1,则输出NO。

    数据范围:$ 2 leq N leq 10^{5}, 1 leq M leq 2 imes 10^{5} $

    题解:bfs分层,并记录每个点的父节点即可。

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N = 1e5 + 5;
    vector<int> G[N];
    bool vis[N];
    int f[N];
    int main() {
        int n, m;
        scanf("%d%d", &n, &m);
        for(int i = 0, u, v; i < m; i++) {
            scanf("%d%d", &u, &v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        queue<int> qu;
        qu.push(1), vis[1] = true;
        while(!qu.empty()) {
            int u = qu.front();
            qu.pop();
            for(auto v : G[u]) {
                if(vis[v]) continue;
                f[v] = u;
                qu.push(v), vis[v] = true;
            }
        }
        bool flag = false;
        for(int i = 1; i <= n; i++) {
            if(!vis[i]) flag = true;
        }
        if(flag) {
            printf("No
    ");
            return 0;
        }
        printf("Yes
    ");
        for(int i = 2; i <= n; i++) {
            printf("%d
    ", f[i]);
        }
        return 0;
    }
    D.cpp

     E - ∙ (Bullet)

    题意:有N个物品,每个物品有A,B属性,要求取一个子集,满足子集内的任何两个物品i,j,Ai*Bj +Aj*Bi != 0,求有多少个方案数。(mod 1e9 + 7)

    数据范围:$ 1 leq N leq 2 imes 10^{5}, -10^{18} leq A_{i}, B_{i} leq 10^{18} $

    题解:可以将A/B看成斜率,那么问题转化成选的集合内不能有垂直的线(A = B = 0除外)。二维平面下不可能存在a垂直b,b垂直c,c垂直a的情况。

    所以将物品按斜率分类,假如没有与它垂直的线,那方案数2^num次(num代表斜率为它的个数),假如有的话,2^num1- 1 + 2^num2 - 1 + 1。

    A=B=0比较特殊,取了它以后,别的都不能取,所以只要加上num(A=B=0)即可,最后在减去空集的情况。

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int MD = 1e9 + 7;
    map<pair<ll, ll>, int> ma;
    int quick_pow(int x, int y) {
        int ans = 1;
        while(y) {
            if(y & 1) ans = 1LL * ans * x % MD;
            y >>= 1;
            x = 1LL * x * x % MD;
        }
        return ans;
    }
    int main() {
        int n, s = 0;
        scanf("%d", &n);
        for(int i = 0; i < n; i++) {
            ll a, b;
            scanf("%lld%lld", &a, &b);
            ll d = __gcd(a, b);
            if(d == 0) {
                s++;
                continue;
            }
            a /= d, b /= d;
            if(a < 0) a = -a, b = -b;
            ma[{a, b}]++;
        }
        ll ans = 1;
        for(auto it : ma) {
            if(it.second == 0) continue;
            ll a = it.first.first, b = it.first.second;
            ll d = quick_pow(2, ma[{a, b}]);
            b = -b;
            if(b < 0) a = -a, b = -b;
            if(ma.count({b, a})) {
                d = (d + quick_pow(2, ma[{b, a}]) - 1) % MD;
                ma[{b, a}] = 0;
            }
            ans = ans * d % MD;
        }
        ans = (ans - 1 + s + MD) % MD;
        printf("%lld
    ", ans);
        return 0;
    }
    E.cpp

    F - . (Single Dot)

    题意:在二维平面内给若干个平行x轴和平行y轴的线段,不能走在线段上和穿过线段,求从(0,0)能到达的地方的面积,若为无限,输出INF。

    数据范围:$ 1 leq N, M leq 1000, -10^{9} leq All values leq 10^{9} $

    题解:将线段上的点离散化,然后bfs求出块面积即可,具体看代码。

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N = 1005;
    const int M = 7005;
    int a[N], b[N], c[N], d[N], e[N], f[N];
    vector<int> vx, vy;
    int dx[] = {0, 0, -1, 1}, dy[] = {-1, 1, 0, 0};
    bool ma[M][M], vis[M][M];
    int get_x(int x) {
        return lower_bound(vx.begin(), vx.end(), x) - vx.begin();
    }
    int get_y(int x) {
        return lower_bound(vy.begin(), vy.end(), x) - vy.begin();
    }
    int main() {
        int n, m;
        scanf("%d%d", &n, &m);
        vx.push_back(-1.1e9), vx.push_back(0);
        vy.push_back(-1.1e9), vy.push_back(0);
        for(int i = 0; i < n; i++) {
            scanf("%d%d%d", &a[i], &b[i], &c[i]);
            vx.push_back(a[i]), vx.push_back(b[i]);
            vy.push_back(c[i]);
        }
        for(int i = 0; i < m; i++) {
            scanf("%d%d%d", &d[i], &e[i], &f[i]);
            vy.push_back(e[i]), vy.push_back(f[i]);
            vx.push_back(d[i]);
        }
        sort(vx.begin(), vx.end()), vx.erase(unique(vx.begin(), vx.end()), vx.end());
        sort(vy.begin(), vy.end()), vy.erase(unique(vy.begin(), vy.end()), vy.end());
        for(int i = 0; i < n; i++) {
            a[i] = get_x(a[i]), b[i] = get_x(b[i]), c[i] = get_y(c[i]);
            for(int j = a[i] * 2 - 1; j < 2 * b[i]; j++) {
                ma[j][2 * c[i] - 1] = true;
            }
        }
        for(int i = 0; i < m; i++) {
            d[i] = get_x(d[i]), e[i] = get_y(e[i]), f[i] = get_y(f[i]);
            for(int j = 2 * e[i] - 1; j < 2 * f[i]; j++) {
                ma[2 * d[i] - 1][j] = true;
            }
        }
        int sx = get_x(0) * 2 - 1, sy = get_y(0) * 2 - 1;
        bool flag = false;
        ll ans = 0;
        queue<pair<int, int>> qu;
        qu.push({sx, sy}), vis[sx][sy] = true;
        while(!qu.empty()) {
            int ux = qu.front().first, uy = qu.front().second;
            qu.pop();
            if(ux == M - 1 || uy == M - 1 || ux == 0 || uy == 0) {
                flag = true;
                break;
            }
            if(ux % 2 == 0 && uy % 2 == 0) {
                int x = ux / 2, y = uy / 2;
                ans += 1LL * (vx[x + 1] - vx[x]) * (vy[y + 1] - vy[y]);
            }
            for(int i = 0 ; i < 4; i++) {
                int xx = ux + dx[i], yy = uy + dy[i];
                if(xx >= M || xx < 0 || yy >= M || yy < 0 || vis[xx][yy] || ma[xx][yy]) continue;
                qu.push({xx, yy}), vis[xx][yy] = true;
            }
        }
        if(flag) printf("INF
    ");
        else printf("%lld
    ", ans);
        return 0;
    }
    F.cpp
  • 相关阅读:
    word20170108逛景点 Sightseeing有用的词和句子
    c# List 分页问题
    VUE界面,this.form.xxx=1赋值后,界面效果没有变化
    SQL Server使用索引视图来实现“物化视图”
    .NET CORE 实现异步处理
    当请求接口提示网络错误Error:Network Error的时候
    SheetJS js-xlsx :js实现导出Excel模板
    增加索引分析
    聚集索引与非聚集索引的总结
    Dynamics CRM-无法识别安全令牌的颁发者,若要接受来自此颁发者的安全令牌,请将 IssuerNameRegistry 配置为返回此颁发者的有效名称
  • 原文地址:https://www.cnblogs.com/zdragon1104/p/12907378.html
Copyright © 2020-2023  润新知