AtCoder Beginner Contest 376(ABCDE个人题解)

A:
没什么好说的,简单模拟一下

AC代码:
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=2e5+10,mod=1e9+7;
void solve() {
    int n, c;
    cin >> n >> c;
    vector<int> a(n + 1);
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    int ans = 0;
    int cnt = a[1];
    for (int i = 2; i <= n; i++) {
        if (a[i] - cnt >= c) {
            ans++;
            cnt = a[i];
        }
    }
    cout << ans + 1 << endl;
}
signed main() {
    ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
//    int t;
//    cin >> t;
//    while (t--)
        solve();
    return 0;
}

B:
本来想找一个简单巧妙的方法,最后还是老老实实暴力过的,就是分俩种情况,看另一只手是在顺时针方向还是逆时针方向,就暴力if判断。
AC代码:

#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=2e5+10,mod=1e9+7;
void solve() {
    int n, q;
    cin >> n >> q;
    int l = 1, r = 2;
    int ans = 0;
    while (q--) {
        char c;
        int x;
        cin >> c >> x;
        if (c == 'L') {
            if (x > l) {
                if (r > l && r < x) {
                    ans += n - x + l;
                } else {
                    ans += x - l;
                }
            } else {
                if (r > x && r < l) {
                    ans += n - l + x;
                } else {
                    ans += l - x;
                }
            }
            l = x;
        } else {
            if (x > r) {
                if (l > r && l < x) {
                    ans += n - x + r;
                } else {
                    ans += x - r;
                }
            } else {
                if (l > x && l < r) {
                    ans += n - r + x;
                } else {
                    ans += r - x;
                }
            }
            r = x;
        }
    }
    cout << ans << endl;
}
signed main() {
    ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
//    int t;
//    cin >> t;
//    while (t--)
        solve();
    return 0;
}

C:
这题我一开始想太多了,用二分去做的,然后WA了一发,仔细看了看,贪心O(n)就能解决。
优先先把大玩具的装入大的盒子里,对两个数组从小到大排序一下,然后从后向前,如果装得下就装,装不下就停止,答案就会是该玩具的大小,另外,还要判断-1的情况,就是除了该玩具之外,还没装的玩具是否都能放入相应的盒子里,只要在往前遍历一下就行了
AC代码:

#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=2e5+10,mod=1e9+7;
void solve() {
    int n;
    cin >> n;
    vector<int> a(n + 1, 0), b(n + 1, 0);
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    for (int i = 1; i <= n - 1; i++) {
        cin >> b[i];
    }
    sort(a.begin() + 1, a.begin() + n + 1);
    sort(b.begin() + 1, b.begin() + n);
    int cnt = n - 1;
    int ans;
    for (int i = n; i >= 1; i--) {
        if (a[i] <= b[cnt]) {
            cnt--;
        } else {
            ans = a[i];
            break;
        }
    }
    for (int i = cnt; i >= 1; i--) {
        if (a[i] > b[i]) {
            cout << -1 << endl;
            return;
        }
    }
    cout << ans << endl;
}
signed main() {
    ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
//    int t;
//    cin >> t;
//    while (t--)
        solve();
    return 0;
}

D:
题意就是找经过1点的最小环,本人用最短路做的,dijkstra从源点1开始,复杂度 O((N+M)*logN),当源点 s的所有邻点都被松弛后,重新将 s 设置为未访问,则 d[s] 就是 s 所在最小环长度,也就是从该点到源点跑最短路就行了,但是,该方法不能在无向图中使用 否则会直接走回源点 s。
AC代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10,inf=0x3f3f3f3f;
int n,m,c,ans,d[N],vis[N],mn=0x3f3f3f3f;
struct node{
    int v,w;
};
vector<node> e[N];
struct node1 {
    int x, y;
};
struct cmp {bool operator()(const node1 &a, const node1 &b) const {return a.x > b.x;}};
void dj(int s) {
    priority_queue<node1,vector<node1>,cmp> q;
    for (int i = 1; i <= n; i++) {
        d[i] = inf;
        vis[i] = 0;
    }
    d[s] = 0;
    q.push({0, s});
    int flg = 1; //用于标记源点已经设置为未访问
    while (!q.empty()) {
        auto t = q.top();
        q.pop();
        int u = t.y;
        if (!flg && u == s)//剪枝
            break;
        if (vis[u]) continue;
        vis[u] = 1;
        for (auto k: e[u]) {
            int v = k.v, w = k.w;
            if (d[v] > d[u] + w) {
                d[v] = d[u] + w;
                q.push({d[v], v});
            }
        }
        if(flg){ //将源点设置为未访问
            vis[s]=0,d[s]=inf;
            flg=0;
        }
    }
}
void solve() {
    ans = 0;
    cin >> n >> m;
    for (int i = 1; i <= m; i++) {
        int u, v, p;
        cin >> u >> v;
        e[u].push_back({v, 1});
    }
    dj(1);
    if(d[1]==inf){
        cout<<-1<<endl;
    }
    else{
        cout<<d[1]<<endl;
    }
}
signed main() {
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
//    int t;
//    cin>>t;
//    while (t--)
    solve();
    return 0;
}

E:
按照a的大小对两个数组进行从小到大排序。
在枚举的过程中,用堆来维护b数组的前k小数即可。

#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=2e5+10,mod=1e9+7;
typedef pair<int,int> PII;
PII v[N];
void solve() {
    int n, k;
    cin >> n >> k;
    for (int i = 1; i <= n; i++) {
        cin >> v[i].first;
    }
    for (int i = 1; i <= n; i++) {
        cin >> v[i].second;
    }
    sort(v + 1, v + 1 + n);
    priority_queue<int> q;
    int sum = 0;
    for (int i = 1; i <= k; i++) {
        q.push(v[i].second);
        sum += v[i].second;
    }
    int ans = sum * v[k].first;
    for (int i = k + 1; i <= n; i++) {
        ans = min(ans, v[i].first * (sum - q.top() + v[i].second));
        if (v[i].second < q.top()) {
            sum = sum - q.top() + v[i].second;
            q.pop();
            q.push(v[i].second);
        }
    }
    cout << ans << endl;
}
signed main() {
    ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t;
    cin >> t;
    while (t--)
        solve();
    return 0;
}
posted @ 2024-10-20 01:47  _LXYYYY  阅读(37)  评论(0编辑  收藏  举报