zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    JavaSE 基础 第51节 定义自己的异常
    JavaSE 基础 第50节 Java中的异常链
    JavaSE 基础 第49节 手动抛出异常
    JavaSE 基础 第48节 Java中的异常声明
    JavaSE 基础 第47节 获取异常信息
    JavaSE 基础 第46节 异常的分类
    JavaSE 基础 第45节Java异常快速入门
    JavaSE 基础 第44节 引用外部类的对象
    JavaSE 基础 第43节 静态内部类
    通用爬虫
  • 原文地址:https://www.cnblogs.com/zdragon1104/p/12907378.html
Copyright © 2011-2022 走看看