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\n");
    else if(n == 0 || n == 1 || n == 6 || n == 8) printf("pon\n");
    else printf("bon\n");
    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("...\n");
    }else {
        printf("%s\n", 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\n", 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 \times 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\n");
        return 0;
    }
    printf("Yes\n");
    for(int i = 2; i <= n; i++) {
        printf("%d\n", 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 \times 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\n", 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\n");
    else printf("%lld\n", ans);
    return 0;
}
F.cpp

 

posted @ 2020-05-18 13:09  zdragon  阅读(428)  评论(0编辑  收藏  举报