AtCoder Beginner Contest 366

A题:Election 2

题意

两个人进行选举,已知部分投票情况,问最后结果是否一定

思路

由题意,如果结果定的话,那么就算没投票的全投给当前票少的,也不会改变结果

代码

#include <iostream>
using namespace std;
int main() {
    int n, a, b; cin >> n >> a >> b;
    if (a > b) swap(a, b);
    cout << ((n - b > b) ? "No" : "Yes") << endl;
    return 0;
}

B题: Vertical Writing

题意

将给定的N个字符串整体顺时针旋转90度,并且对于旋转后的字符串,从右往左看,“高度”不减,对于少的部分用*填补

思路

单调不减,维护一个遇到的最大值,如果当前的字符串大小小于这个值,那么就要加上*,大于的话进行更新。然后对于旋转操作,我们只需要改变输出即可。

代码

#include <iostream>
#include <vector>
using namespace std;
int main() {
    int n; cin >> n;
    vector<string> a(n);
    for (int i = 0; i < n; i ++ ) cin >> a[i];
    int cur = a[0].size();
    for (int i = 1; i < n; i ++ ) {
        a[i] += string(max(0, cur - (int)a[i].size()), '*');
        cur = max(cur, (int)a[i].size());
    }
    for (int i = 0; i < cur; i ++ ) {
        for (int j = n - 1; ~j; j -- ) {
            if (a[j].size() < i + 1) cout << ' ';
            else cout << a[j][i];
        }
        cout << endl;
    }
    return 0;
}

C题:Balls and Bag Query

题意

有三种操作,分别为

1.放入一个x。 2.拿出一个x。 3.输出当前不同的整数数量

思路

用map模拟即可

代码

#include <iostream>
#include <map>
using namespace std;
int main() {
    int q; cin >> q;
    map<int, int> p;
    while (q -- ) {
        int op, x; cin >> op;
        if (op == 1) {
            cin >> x;
            p[x] += 1;
        }else if (op == 2) {
            cin >> x;
            if (-- p[x] == 0) p.erase(x);
        }else {
            cout << p.size() << endl;
        }
    }
    return 0;
}

D题:Cuboid Sum Query

题意

可以看作有n个二维数组,然后要求你求其中的和

思路

我们可以做n个二维前缀和,因为N值很小,那么只需要最后的时候用for将其中的所有前缀和加一起即可

#include <iostream>
using namespace std;
int a[110][110][110];
int main() {
    int n; cin >> n;
    for (int i = 1; i <= n; i ++ ) {
        for (int j = 1; j <= n; j ++ ) {
            for (int k = 1; k <= n; k ++ ) {
                cin >> a[i][j][k];
                a[i][j][k] += a[i][j - 1][k] + a[i][j][k - 1] - a[i][j - 1][k - 1];
            }
        }
    }
    int q; cin >> q;
    while (q -- ) {
        int x[3], y[3]; cin >> x[0] >> y[0] >> x[1] >> y[1] >> x[2] >> y[2];
        int ans = 0;
        for (int i = x[0]; i <= y[0]; i ++ ) {
            ans += a[i][y[1]][y[2]] - a[i][x[1] - 1][y[2]] - a[i][y[1]][x[2] - 1] + a[i][x[1] - 1][x[2] - 1];
        }
        cout << ans << endl;
    }
    return 0;
}

E题:Manhattan Multifocal Ellipse

题意

求二维平面上,与其他N个点曼哈顿距离总和小于等于D的点的数量

思路

对于所有的点的曼哈顿距离,可以先求x的,再求y的,不必拘泥于一个一个点求,这是解决这道题的第一点

然后,我们看x

我们可以用前缀和来求对于x坐标上曼哈顿距离总和在0~D的点的数量

然后同理,可以求y的

因为是小于等于D,我们在求完x的时候,可以对dist数组做一个求前缀和的操作,

那么在y操作的时候,可以直接在答案上加上d-len即可

代码

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
using LL = long long;
int main() {
    int n, d; cin >> n >> d;
    vector<int> x(n + 1), y(n + 1);
    for (int i = 1; i <= n; i ++ ) cin >> x[i] >> y[i];
    sort(x.begin() + 1, x.end()), sort(y.begin() + 1, y.end());
    vector<LL> pre(n + 1);
    vector<LL> dist(d + 1);
    for (int i = 1; i <= n; i ++ ) pre[i] = pre[i - 1] + x[i];
    for (int i = x[1] - d, j = 1; i <= x[n] + d; i ++ ) {
        while (j <= n && i == x[j]) j += 1;
        LL len = (pre[n] - pre[j - 1] - (LL)(n - j + 1) * i) + ((LL)(j - 1) * i - pre[j - 1]);
        if (len <= d) dist[len] += 1;
    }
    for (int i = 1; i <= d; i ++ ) dist[i] += dist[i - 1];
    for (int i = 1; i <= n; i ++ ) pre[i] = pre[i - 1] + y[i];
    LL ans = 0;
    for (int i = y[1] - d, j = 1; i <= y[n] + d; i ++ ) {
        while (j <= n && i == y[j]) j += 1;
        LL len = (pre[n] - pre[j - 1] - (LL)(n - j + 1) * i) + ((LL)(j - 1) * i - pre[j - 1]);
        if (len <= d) ans += dist[d - len];
    }
    cout << ans << endl;
    return 0;
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值