2024年暑假ACM集训第6场

A: 文件存储

题目描述

如果有n个文件{F1,F2,F3,...,Fn}需要存放在大小为M的U盘中,文件i的大小为Si,1<=i<=n。请设计一个算法来提供一个存储方案,使得U盘中存储的文件数量最多。

输入

多组输入,对于每组测试数据,每1行的第1个数字表示U盘的容量M(以MB为单位,不超过256*1000MB),第2个数字表示待存储的文件个数n。

第2行表示待存储的n个文件的大小(以MB为单位)。

输出

输出最多可以存放的文件个数。

样例输入 Copy
复制代码
10000 5
2000 1000 5000 3000 4000
样例输出 Copy
复制代码
4
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cmath>
#include <unordered_map>
using namespace std;
int a[256005];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int m, n;
    while (cin >> m >> n)
    {
        for (int i = 0; i < n; i++)
            cin >> a[i];
        sort(a, a + n);
        int sum = 0;
        int t = 0;
        for (int i = 0; i < n; i++)
        {
            if (m - sum >= a[i])
            {
                sum += a[i];
                t++;
            }
            else
                break;
        }
        cout << t << "\n";
    }
    return 0;
}

B: 汽车加油问题

题目描述

一辆汽车加满油后可以行驶n千米。旅途中有k个加油站。若要使沿途的加油次数最少,请设计一个有效的算法。

输入

第一行有2个正整数n和k,表示汽车加满油后可行驶nkm,且旅途中有k个加油站。接下来1行中,有k+1个整数,表示第k个加油站与第k-1个加油站之间的距离。第0个加油站表示出发地,汽车已加满油,且在第0个加油站满油不算加油,第k+1个加油站表示目的地。(请处理到文件尾)

输出

最少加油次数。如果无法到达目的地,则输出"No Solution"。

样例输入 Copy
复制代码
7 7
1 2 3 4 5 1 6 6
样例输出 Copy
复制代码
4
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cmath>
#include <unordered_map>
using namespace std;
int a[10005];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, k;
    while (cin >> n >> k)
    {
        int s = n, sum = 0;
        for (int i = 0; i <= k; i++)
            cin >> a[i];
        for (int i = 0; i <= k; i++)
        {
            if (a[i] > n)
            {
                cout << "No Solution" << "\n";
                return 0;
            }
            if (s - a[i] >= 0)
                s -= a[i];
            else
            {
                sum++;
                s = n - a[i];
            }
        }
        cout << sum << "\n";
    }
    return 0;
}

C: 遥望基地

题目描述

X星人迷失在Y星球,他必须尽快赶到在Y星球的基地,否则会耗尽所有能量而化成雕像。

现在X星人面前有N种能量药水,每一种药水都有一个体积和维持能量的距离(单位:光日,即光一天所走的距离),每次只能使用一种药水。当然一种药水用完后可以立即更换另一种药水。

X星人拥有一个体积为V的能量药水箱,可以通过药水箱携带若干种不同的能量药水。对于某一种能量药水,可以全部携带,也可以只携带一部分。
**已知X星人当前距离基地M光日,请问X星人会变成雕像吗?**当然,聪明的X星人每次都会尽量让自己走得最远。

输入

单组输入。

第1行输入三个正整数N、M和V,分别表示能量药水的数量、当前X星人与基地之间的距离(光日)和能量药水箱的体积,用空格隔开。(N,M,V\<=10\^4)

接下来N行,每行两个正数(不一定是正整数),分别表示一种药水的体积和能够维持能量的距离(光日),两个正数之间用空格隔开。

输出

如果X星人会变成雕像则输出"Yes",否则输出"No"。

样例输入 Copy
复制代码
3 20 10
5 5
5 10
5 7.5
样例输出 Copy
复制代码
No
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cmath>
#include <unordered_map>
using namespace std;
struct S
{
    double v, s;
} a[10005];
bool cmp(S a, S b)
{
    return a.s > b.s;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, m, V;
    cin >> n >> m >> V;
    for (int i = 0; i < n; i++)
    {
        cin >> a[i].v >> a[i].s;
        a[i].s /= a[i].v;
    }
    sort(a, a + n, cmp);
    double sum = 0;
    for (int i = 0; i < n; i++)
        if (V > a[i].v)
        {
            V -= a[i].v;
            sum += a[i].v * a[i].s;
        }
        else
        {
            sum += V * a[i].s;
            break;
        }
    if (m > sum)
        cout << "No\n";
    else
        cout << "Yes\n";
    return 0;
}

D: 最少代价

题目描述

X星人接到返回总部的紧急命令,他在驻地积蓄了满满的能量开始朝总部前进。为了能够在路上顺利获得能量补给,他带上了n枚X星币。

在驻地通往总部的路上有m个能量补给点,每补给一次X星人将损失一枚X星币。补给过后X星人又将能量满满,这些能量可以供X星人前行k千米。

X星人希望以最少的代价(损失的X星币最少)到达总部,请输出X星人最多可以剩多少枚X星币?

【注意:X星人出发时必然能量满满。】

输入

每组输入数据包含两行。

第1行包含三个用空格分隔开的正整数,分别对应n,m和k。(1 ≤ n ≤ 10000, 1 ≤ m ≤ 2000, 1 ≤ k ≤ 10000)

第2行包含m+1个正整数,两两之间用空格隔开。前面m个数字分别表示出发点到m个补给点的距离(距离小于10000),最后一个数字表示出发点到总部的距离。

输出

每组输出占1行,输出X星人最多还剩下的X星币数量。

如果X星人不能成功到达总部,则输出"No"。

样例输入 Copy
复制代码
10 5 6
2 4 8 12 14 20
样例输出 Copy
复制代码
7
#include <iostream>
#include <algorithm>
using namespace std;
int a[2005];
int main()
{
    int n, m, k;
    while (cin >> n >> m >> k)
    {
        for (int i = 1; i <= m + 1; i++)
            cin >> a[i];
        bool t = true;
        sort(a + 1, a + 2 + m);
        if (k < a[1])
            cout << "No" << '\n';
        else
        {
            int s = k;
            s -= a[1];
            for (int i = 2; i <= m + 1; i++)
            {
                if (s >= a[i] - a[i - 1])
                    s -= a[i] - a[i - 1];
                else
                {
                    s = k;
                    if (s < a[i] - a[i - 1])
                    {
                        t = false;
                        cout << "No" << '\n';
                        break;
                    }
                    s -= a[i] - a[i - 1];
                    n--;
                }
            }
            if (t)
                if (n > 0)
                    cout << n << '\n';
                else
                    cout << "No" << '\n';
        }
    }
    return 0;
}

E: 最小积分

题目描述

Kimi和Sunny决定在线组队玩一个数字游戏,该游戏的规则如下:

(1) 游戏系统随机生成两组正整数,每组N个数字,两组正整数可能不一样;

(2) 每个游戏团队两个人,每个人拿其中一组数字;

(3) 每一轮两个人从自己的那组数字中各取出一个数字,将两个数字相乘作为这一轮的积分,取出的数字不能再重复使用;

(4) 一共玩N轮,将每轮的积分求和,得到一个总积分;

(5) 总积分最小的队伍获胜。

现在需要你编写一个程序帮Kimi和Sunny计算出最小积分和。

输入

单组输入。

第1行输入一个正整数N,N不超过100。

第2行输入N个不超过1000的正整数,表示Kimi拿到的数字,两两之间用空格隔开。

第3行输入N个不超过1000的正整数,表示Sunny拿到的数字,两两之间用空格隔开。

输出

输出最小积分和。

样例输入 Copy
复制代码
3
3 1 2
4 3 5
样例输出 Copy
复制代码
22
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cmath>
#include <unordered_map>
using namespace std;
int a[105], b[105];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> a[i];
    for (int i = 0; i < n; i++)
        cin >> b[i];
    sort(a, a + n);
    sort(b, b + n, greater<int>());
    int sum = 0;
    for (int i = 0; i < n; i++)
        sum += a[i] * b[i];
    cout << sum << "\n";
    return 0;
}

F: HNUCM的批改作文

题目描述

HNUCM的小王老师给同学们布置了一道小作文题,要求所有同学同时提交并现场批改。

批改完的同学即可以下课,否则就需要等待老师把自己的作文批改完才能够下课。

交小作文的时间到了,N个同学同时把作文提交给了小王老师,小王老师根据大家写的字数估算了一下批改时间(单位:分钟),现在请你编写一个程序帮助小王老师做一个决策,使得所有同学等待作文批改的平均时间最少,请输出最少平均等待时间(单位:分钟)。

输入

单组输入。

第1行输入一个不超过100的正整数N。

第2行输入N个不超过20的正整数,每一个正整数对应一个同学的作文批改时间(单位:分钟),两个正整数之间用英文空格分隔。

输出

输出所有同学的作文都批改完时的最少平均等待时间(单位:分钟),结果四舍五入保留两位小数。

样例输入 Copy
复制代码
3
10 5 20
样例输出 Copy
复制代码
18.33
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
int a[100];
int main()
{
 
    int n;
    cin>>n;
    double f=0,s=0;
        for(int i=0;i<n;i++)
        cin>>a[i];
    sort(a,a+n);
    for(int i=0;i<n;i++)
        {
            s+=a[i];
            f+=s;}
    printf("%.2lf",f/n);
}

G: X星人的礼物

题目描述

六一儿童节到了,X星人宝宝收到了很多很多礼物。他决定把这些礼物装到自己的礼物箱中。为此,他准备了很多个型号相同的礼物箱,每个礼物箱能够装礼物的最大重量都是一样的 。但是X星人宝宝不希望在一个礼物箱里面装太多礼物(可能担心礼物会被压坏吧),每个礼物箱最多只允许装2个礼物

假设X星人宝宝收到了N个礼物,现在给出每一个礼物的重量和一个礼物箱的最大装载量,请你编写一个程序计算X星人宝宝最少要用多少个礼物箱才能够把所有的礼物都装完

输入

单组输入。

每组两行,第1行输入两个正整数,分别表示礼物的数量N和每个礼物箱的最大装载量C,其中1<=N<=1000,1<=C<=100,两者之间用英文空格隔开。

第2行输入N个不超过100的正整数,分别表示每一个礼物的重量,两两之间用英文空格隔开。
输入保证最重的礼物的重量<=C。

输出

针对所输出的数据,输出将所有的礼物全部都装完所需的礼物箱的最少个数。

样例输入 Copy
复制代码
5 80
20 70 40 30 10
样例输出 Copy
复制代码
3
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cmath>
#include <unordered_map>
using namespace std;
int a[1005];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < n; i++)
        cin >> a[i];
    sort(a, a + n);
    int l = 0, r = n - 1;
    int s = 0;
    while (l <= r)
    {
        if (a[l] + a[r] <= m)
        {
            l++;
            r--;
        }
        else
        {
            r--;
        }
        s++;
    }
    cout << s << "\n";
    return 0;
}

H: 小h的规划

题目描述

小h是一个很有规划的人,他列了很多事情,标注了优先级(1-9)也标注了必要程度(1-5)必要程度大的排前面,必要程度一样优先级大的排前面,必要程度一样,优先级一样不改变初始顺序。因为事情太多了,所以小h需要你帮忙..

输入

第一行一个数字n表示有n个事情

后n行每行两个数字a,b表示事情的优先级和必要程度

(n<=10000)

输出

将所有事情排序输出(只输出初始序号)

样例输入 Copy
复制代码
2
9 3
1 4
样例输出 Copy
复制代码
2 1
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cmath>
#include <unordered_map>
using namespace std;
struct S
{
    int id;
    int x;
    int y;
} a[10005];
bool cmp(S x, S y)
{
    if (x.y != y.y)
        return x.y > y.y;
    if (x.x != y.x)
        return x.x > y.x;
    return x.id < y.id;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i].x >> a[i].y;
        a[i].id = i;
    }
    sort(a + 1, a + n + 1, cmp);
    for (int i = 1; i <= n; i++)
        cout << a[i].id << " ";
    cout << "\n";
    return 0;
}

I: 李华上大学了吗?(III)

题目描述

李华顺利地到达了巴黎,他的笔友Peter带他开启了他的巴黎之旅。

途中,李华遇到了许多心动的纪念品想要带回家,但是他又不想自己太累,而且他买纪念品也有相应的预算k,现给出他心动的纪念品清单:共有n件,其中每件都各有其价格price,重量weight,心动值v(其中心动值为1~5之间的数值),需要注意的是:在心动值不同的情况下,李华会优先选择心动值大的纪念品;若心动值相同,李华会优先选择比较便宜的纪念品,具体见样例。同时给出李华在保证不累的情况下,最多能拿的物品重量m。在不超过预算并且保证不累的情况下,李华最多可以带几件纪念品回家?

输入

第一行三个整数,分别为:纪念品件数n,最多能拿的物品重量m,预算k。(n<1e5,m<100,k<10000,k的单位为元,m的重量为kg)

第二行到第n+1行,分别为每件物品的价格price,重量weight,心动值v。(price<10000,weight<100,v为1~5之间的整数,price的单位为元,weight的重量为kg)

输出

在不超过预算并且保证不累的情况下,李华最多可以带回家的纪念品件数。

样例输入 Copy
复制代码
3 10 1000
100 5 3
50 3 2
300 3 3
样例输出 Copy
复制代码
2
提示

由于李华会优先选择心动值大的物品,所以李华选择了第一件和第三件物品。

#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cmath>
#include <unordered_map>
using namespace std;
struct S
{
    int pri, wei, v;
} a[100005];
bool cmp(S a, S b)
{
    if (a.v == b.v)
    {
        if (a.pri == b.pri)
            return a.wei < b.wei;
        return a.pri < b.pri;
    }
    return a.v > b.v;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, m, k;
    cin >> n >> m >> k;
    for (int i = 0; i < n; i++)
        cin >> a[i].pri >> a[i].wei >> a[i].v;
    sort(a, a + n, cmp);
    int s = 0, w = 0, p = 0;
    for (int i = 0; i < n; i++)
        if (w + a[i].wei <= m && p + a[i].pri <= k)
        {
            w += a[i].wei;
            p += a[i].pri;
            s++;
        }
    cout << s << "\n";
    return 0;
}

J: 消灭病毒

题目描述

小明最近喜欢上了一款"消灭病毒"的游戏。游戏中有各种各样不同的病毒,消灭的病毒越多,得分越高。但是在游戏中,玩家一旦被病毒击中将减少一定的生命值。

在游戏中,玩家可以通过添加不同的药水来获取生命值。生命值越高,在游戏中存活的时间越长。

游戏一共提供了N种药水,第i种药水的体积为V(i),补充的生命值为L(i)。

玩家可以携带一个体积为V的药水瓶。每一种药水可以全部装入药水瓶,也可以只装入一部分。当然,如果你装入一部分药水,那么也只能补充这一部分药水按比例对应的生命值。

请问如何装入药水可以使得初始的生命值最大?请输出最大的初始生命值。

输入

单组输入。

第1行输入两个正整数V和N,分别表示药水瓶的体积和药水的种类数。(N<=100)

接下来N行,每行包含两个正整数,分别对应第i种药水的体积V(i)和生命值L(i)。

输出

输出最大的初始生命值(四舍五入保留两位小数)。

样例输入 Copy
复制代码
10 3
5 6
3 3
4 2
样例输出 Copy
复制代码
10.00
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cmath>
#include <unordered_map>
using namespace std;
struct S
{
    double x, y;
} a[105];
bool cmp(S a, S b)
{
    return a.y > b.y;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    double v;
    cin >> v >> n;
    for (int i = 0; i < n; i++)
    {
        cin >> a[i].x >> a[i].y;
        a[i].y /= a[i].x;
    }
    sort(a, a + n, cmp);
    double s = 0;
    for (int i = 0; i < n; i++)
        if (v >= a[i].x)
        {
            v -= a[i].x;
            s += a[i].x * a[i].y;
        }
        else
        {
            s += v * a[i].y;
            break;
        }
    printf("%.2lf\n", s);
    return 0;
}

K: 破解密码

题目描述

X星人最近截取了Y星人的一段数字密文,这是一段长度为N(N>=2)的十进制正整数数字密文,且第1位是非零数。

聪明的X星人通过仔细分析和研究,终于找到了破解方法。破解过程非常复杂,包含若干步骤,其中第一步如下:

这段数字密文的第1位是一个密钥,设该密钥为K(K<N)。从这段数字密文中去掉K个数字后将得到一个新的正整数,其中所得到的最大正整数即为可用于进一步处理的中间码。

你能否编写一段程序帮助X星人将数字密文转换为对应的中间码?

输入

单组输入。

每组一行,输入一个长度为N的十进制正整数。(2<=N<=1000)

输出

输出数字密文所对应的中间码。

样例输入 Copy
复制代码
246135
样例输出 Copy
复制代码
6135
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cmath>
#include <unordered_map>
using namespace std;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    string a;
    cin >> a;
    int k = a[0] - '0';
    int n = a.size();
    string s = "";
    for (int i = 0; i < n; i++)
    {
        if (n - i <= k)
            break;
        int x = -1, y = -1;
        for (int j = i; j <= k + i; j++)
            if (a[j] - '0' > x)
            {
                x = a[j] - '0';
                y = j;
            }
        s += to_string(x);
        k -= y - i;
        i = y;
    }
    cout << s << "\n";
    return 0;
}

L: 奥运日

题目描述

由于受到新冠肺炎疫情的影响,2020东京奥运会在推迟一年后终于举行啦!即便是在暑假,"爱学习"的小米同学每周也只能有一天时间看奥运会的比赛。

今天的比赛异常精彩,很多项目都来到了最后的决赛。小米是个有强迫症的小伙子,如果他决定看一个比赛项目,就希望能够从头到尾完整地看完。

已知有2个电视频道在全天转播奥运电视节目,现给出这2个电视频道的节目转播时间表,请问小米最多可以看多少个完整的比赛项目(每个比赛项目对应一个电视节目)?

注:为了对问题进行简化,节目转播时间表只包含比赛项目的开始时间和结束时间(开始时间计入比赛时间,结束时间不计入比赛时间),且不考虑2个电视频道之间的切换时间,2个电视频道转播的比赛项目也不存在重复。

输入

单组输入。

第1行输入两个正整数M和N,分别表示两个电视频道转播的比赛项目(电视节目)的个数,二者之间用空格隔开,每个电视频道每一天的总节目数不超过30个。

接下来输入2行,每1行表示1个电视频道的节目转播时间表,每一个电视节目的开始时间和结束时间用24小时制表示,包含小时和分钟,格式为:HH:MM-HH:MM,例如:11:30-13:40。每两个比赛项目时间之间用空格隔开。

输出

输出这一天小米最多可以观看的完整比赛项目的个数。

样例输入 Copy
复制代码
3 4
08:00-09:00 09:30-11:00 13:00-15:00
07:00-08:00 08:00-11:00 12:00-13:30 14:00-17:00
样例输出 Copy
复制代码
5
提示

小米可以观看第1个频道的第1个、第2个节目,第2个频道的第1个、第3个和第4个项目,总共可以观看5个完整的比赛项目。

#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cmath>
#include <unordered_map>
#include <sstream>
using namespace std;
int m, n, s;
struct S
{
    int l, r;
} a[100];
bool cmp(S x, S y)
{
    return x.r < y.r;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> m >> n;
    for (int i = 1; i <= m; i++)
    {
        int h1, m1, h2, m2;
        char c, d, e;
        cin >> h1 >> c >> m1 >> d >> h2 >> d >> m2;
        a[i].l = h1 * 60 + m1;
        a[i].r = h2 * 60 + m2;
    }
    for (int i = 1; i <= n; i++)
    {
        int h1, m1, h2, m2;
        char c, d, e;
        cin >> h1 >> c >> m1 >> d >> h2 >> d >> m2;
        a[m + i].l = h1 * 60 + m1;
        a[m + i].r = h2 * 60 + m2;
    }
    sort(a + 1, a + 1 + m + n, cmp);
    int sum = 0;
    for (int i = 1; i <= m + n; i++)
        if (a[i].l >= sum)
        {
            s++;
            sum = a[i].r;
        }
    cout << s << endl;
    return 0;
}

M: X星切糕

题目描述

据说在X星上有一种切糕,这种切糕呈细长形状,并且按长度来进行售卖。

更有意思的是,不同长度的切糕其价格不一样。定价规则如下:

1单位长度:价值为3枚X星币。

2单位长度:价值为7枚X星币。

3单位长度:价值为11枚X星币。

4单位长度:价值为15枚X星币。

5单位长度:价值为20枚X星币。

现有一块N个单位长度的切糕,需要将其切成若干小段,每一小段的长度均不超过5个单位长度,请问可以得到的最大价值是多少枚X星币?

输入

单组输入。

输入一个正整数N表示切糕的总长度,N<=10^6。

输出

输出切成小段之后可以得到的最大价值(X星币的枚数)。

样例输入 Copy
复制代码
12
样例输出 Copy
复制代码
47
#include<stdio.h>
int main()
{
    int n,s;
    scanf("%d",&n);
    s=20*(n/5);
    n%=5;
    if(n==4)
        s+=15;
    else if(n==3)
        s+=11;
    else if(n==2)
        s+=7;
    else if(n==1)
        s+=3;
    printf("%d\n",s);
    return 0;
}
相关推荐
凌肖战12 分钟前
力扣上刷题之C语言实现(数组)
c语言·算法·leetcode
秋夫人39 分钟前
B+树(B+TREE)索引
数据结构·算法
梦想科研社1 小时前
【无人机设计与控制】四旋翼无人机俯仰姿态保持模糊PID控制(带说明报告)
开发语言·算法·数学建模·matlab·无人机
Milo_K1 小时前
今日 leetCode 15.三数之和
算法·leetcode
Darling_001 小时前
LeetCode_sql_day28(1767.寻找没有被执行的任务对)
sql·算法·leetcode
AlexMercer10121 小时前
【C++】二、数据类型 (同C)
c语言·开发语言·数据结构·c++·笔记·算法
Greyplayground1 小时前
【算法基础实验】图论-BellmanFord最短路径
算法·图论·最短路径
蓑 羽1 小时前
力扣438 找到字符串中所有字母异位词 Java版本
java·算法·leetcode
源代码:趴菜1 小时前
LeetCode63:不同路径II
算法·leetcode·职场和发展
儿创社ErChaungClub2 小时前
解锁编程新境界:GitHub Copilot 让效率翻倍
人工智能·算法