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;
}