“蔚来杯“2022牛客暑期多校训练营5

"蔚来杯"2022牛客暑期多校训练营5

[题目链接]("蔚来杯"2022牛客暑期多校训练营5_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ (nowcoder.com))

K Headphones

题目大意

有N对耳机,Yasa拿出正好k对,NIO至少要取出多少只,能够比Yasa取出的多。耳机左右为一对,Yasa拿出的都是一对,NIO要取的是一只一只的。

题解

见代码。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5;
int n, k;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    while (cin >> n >> k)
    {
        if ((n - k) * 2 <= n)
            cout << -1 << endl;
        else
            cout << n + 1 << endl;
    }
}

C Bit Transmission

题目大意

有个01组成的字符串,对某些位置询问是否是1,询问3n次,有至多一次询问返回的答案是错误的。问这些询问结果能否唯一确定字符串。

题解

见代码。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5;
int n, x;
string s;
int yes[maxn], no[maxn];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    for (int i = 1; i <= 3 * n; i++)
    {
        cin >> x >> s;
        if (s == "YES")
            yes[x]++;
        else
            no[x]++;
    }
    s = "";
    bool ok = 1;
    for (int i = 0; i < n; i++)
    {
        if (no[i] && yes[i])
        {
            if (ok)
                ok = 0;
            else
            {
                cout << -1 << endl;
                return 0;
            }
            if (yes[i] == 1 && no[i] == 1)
            {
                cout << -1 << endl;
                return 0;
            }
            else if (no[i] == 1)
            {
                s += "1";
            }
            else if (yes[i] == 1)
            {
                s += "0";
            }
            else
            {
                cout << -1 << endl;
                return 0;
            }
        }
        else
        {
            if (no[i])
                s += "0";
            else
                s += "1";
        }
    }
    cout << s << endl;
    return 0;
}

B Watches

题目大意

给定n件商品的价格,如果你选购k件商品,那么购买第i件物品的花费就是ai+k*i,问最多能买多少件(第i件是原序列中的第i个)。

题解

二分+贪心,判定是否能选择k件物品,总花费不超过M元。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5;
int n, m;
int a[maxn], b[maxn];
bool checked(int k)
{
    int ans = 0;
    for (int i = 1; i <= n; i++)
        b[i] = a[i] + k * i;
    sort(b + 1, b + 1 + n);
    for (int i = 1; i <= k; i++)
    {
        ans += b[i];
        if (ans > m)
            return false;
    }
    return true;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    while (cin >> n >> m)
    {
        for (int i = 1; i <= n; i++)
            cin >> a[i];
        int l = 0, r = n, mid, ans;
        while (l <= r)
        {
            mid = (l + r) >> 1;
            if (checked(mid))
            {
                ans = mid;
                l = mid + 1;
            }
            else
            {
                r = mid - 1;
            }
        }
        cout << ans << endl;
    }
}

A Don’t Starve

题目大意

给定n个点有食物(每个点可以吃多次),每个点有一个坐标,对于行走的规则是每一步都必须严格短于上一步,问最优的方案下能够吃到多少次食物。

题解

首先枚举出所有的边,然后从大到小排序,然后每次枚举长度相同的边。

定义f[i]为目前状态下,到达点i获得的最大的食物。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e3 + 5;
const int Max = 0x3f3f3f3f;
int n;
int x[maxn], y[maxn];
struct Edge
{
    int u, v, dis;
    Edge(int u = 0, int v = 0, int dis = 0) : u(u), v(v), dis(dis) {}
    bool operator<(const Edge &a) const
    {
        return dis > a.dis;
    }
};
vector<Edge> e;
int f[maxn], g[maxn];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    memset(f, -Max, sizeof f);
    cin >> n;
    for (int i = 1; i <= n; i++)
        cin >> x[i] >> y[i];
    for (int i = 0; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
            if (i != j)
                e.push_back(Edge(i, j, pow(x[j] - x[i], 2) + pow(y[j] - y[i], 2)));
    }
    sort(e.begin(), e.end());
    f[0] = 0;
    for (int i = 0, j = 0; i < e.size(); i = j)
    {
        vector<Edge> v;
        for (; j < e.size() && e[i].dis == e[j].dis; j++)
            v.push_back(e[j]);
        for (auto e : v)
            g[e.v] = -Max;
        for (auto e : v)
            g[e.v] = max(g[e.v], f[e.u] + 1);
        for (auto e : v)
            f[e.v] = max(f[e.v], g[e.v]);
    }
    cout << *max_element(f, f + n + 1) << endl;
    return 0;
}

H Cutting Papers

题目大意

给出一个不等式,问这个不等式构成的封闭区域和以这个封闭区域中心为圆心的圆形的面积并。

题解

根据不等式画出封闭区域,直接计算圆形和封闭区域的并集。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e3 + 5;
const int pi = acos(-1);
double n;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    cout << fixed << setprecision(10) << n * n * (4 - pi) / 8 << endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值