题目链接
本套题比较难的是C,B和F需要思考一下,其它简单。
A.看电视
题解:很自然可以想到,要么按照开始时间排序,要么按照结束时间排序。按开始时间排,可能最早开始的会占后面开始的两个节目,故排除此方法。所以按照结束时间升序排即可,每次选择最早结束的,可以得到最多的节目。
#include<bits/stdc++.h>
using namespace std;
struct node
{
int s, e;
}a[110];
bool cmp(node a, node b)
{
return a.e < b.e;
}
int main()
{
int n, i;
while (~scanf("%d", &n) && n){
for (i = 0; i < n; i++)
scanf("%d%d", &a[i].s, &a[i].e);
sort(a, a + n, cmp);
int cnt = 0, last_end = 0;
for (i = 0; i < n; i++)
if (a[i].s >= last_end) cnt++, last_end = a[i].e;
printf("%d\n", cnt);
}
}
B. 出租车费
题解:1-4公里2.5元/公里,1-8公里2.25元/公里,再往后每公里费用大于2.25元。所以,每次贪心地选择每辆车坐8公里,剩余路程如果<=4就继续坐下去,否则再坐一辆新的,此方案保证费用最少。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n, i;
while (~scanf("%d", &n) && n){
if (n <= 4) printf("10\n");
else if (n <= 8) printf("%d\n", 10 + (n - 4) * 2);
else{
int num = n / 8, rest = n % 8;
if (!rest) printf("%d\n", num * 18);
else if (rest <= 4) printf("%.1f\n", num * 18 + rest * 2.4);
else printf("%d\n", num * 18 + 10 + (rest - 4) * 2);
}
}
}
C.To Fill or Not to Fill
题解:首先判断汽车不能到达终点的情况:起点没有加油站;相邻两加油站的距离大于汽车的行驶距离。
然后在汽车的行驶距离内寻找更便宜的加油站:如果有,那么汽车要到这个加油站,判断油量是否足够,够就不加油,不够就加油;如果没有,判断下从当前加油站出发能否到终点,能到计算相应油量,不能就加满油,因为当前加油站其实已经是最便宜的了,加满即可。
#include<bits/stdc++.h>
using namespace std;
struct node
{
double pri, dis;
}k[510];
bool cmp(node a, node b)
{
return a.dis < b.dis;//将加油站照位置升序排列
}
int main()
{
double cmax, d, davg;
int n, i, j;
scanf("%lf%lf%lf%d", &cmax, &d, &davg, &n);
for (i = 0; i < n; i++)
scanf("%lf%lf", &k[i].pri, &k[i].dis);
sort(k, k + n, cmp);
k[n].dis = d;
if (k[0].dis){//起点没有加油站
printf("The maximum travel distance = 0.00\n");
return 0;
}
double res = 0, curoil = 0;
double maxdis = cmax * davg;
for (i = 0; i < n; i++){
double curpos = k[i].dis;
if (curpos + maxdis < k[i + 1].dis){//相邻加油站不能到达
printf("The maximum travel distance = %.2lf\n", curpos + maxdis);
break;
}
if (i) curoil -= (k[i].dis - k[i - 1].dis) / davg;
bool ischeap = 0;
for (j = i + 1; j < n; j++){//行驶范围内找更便宜的加油站
double curdis = k[j].dis - k[i].dis;
if (curdis > maxdis) break;
if (k[j].pri < k[i].pri){
double temp = curoil;//当前油量
curoil = curdis / davg;//需要油量
if (temp < curoil) res += (curoil - temp) * k[i].pri;
else curoil = temp;
ischeap = 1;
break;
}
}
if (!ischeap){//没便宜站
if (curpos + maxdis >= d){//能到终点
res += ((d - curpos) / davg - curoil) * k[i].pri;
printf("%.2lf\n", res);
break;
}
else{//不能到终点
res += (cmax - curoil) * k[i].pri;
curoil = cmax;
}
}
}
}
D.Repair the Wall
题意:用若干个可切割的小矩形合成一个大距形,问最少需要多少个小矩形。
题解:每次贪心地选取尺寸最大的小矩形即可,多出来的切割掉。
#include<bits/stdc++.h>
using namespace std;
int a[610];
int main()
{
int l, n, i;
while (~scanf("%d%d", &l, &n)){
for (i = 0; i < n; i++)
scanf("%d", &a[i]);
sort(a, a + n);
long long sum = 0;
bool flag = 0;
int res = 0;
for (i = n - 1; i >= 0; i--){
sum += a[i], res++;
if (sum >= l){
flag = 1;
printf("%d\n", res);
break;
}
}
if (!flag) printf("impossible\n");
}
}
E.FatMouse’s Trade
题意:有m个猫食,fi个猫食可以换ji个java豆,问最多能换多少个java豆。
题解:每次贪心地选取ji/fi最大的一组即可。
#include<bits/stdc++.h>
using namespace std;
struct node
{
double a, b;
}k[1010];
bool cmp(node e, node f)
{
return e.a * f.b > f.a * e.b;
}
int main()
{
int m, n, i;
while (~scanf("%d%d", &m, &n)){
if (m == -1 && n == -1) break;
for (i = 0; i < n; i++)
scanf("%lf%lf", &k[i].a, &k[i].b);
sort(k, k + n, cmp);
double res = 0;
for (i = 0; i < n; i++){
if (m >= k[i].b){
res += k[i].b * k[i].a / k[i].b;
m -= k[i].b;
}
else{
res += m * k[i].a / k[i].b;
m = 0;
}
}
printf("%.3lf\n", res);
}
}
F.迷瘴
题解:由题意得,(p1v+p2v+…+piv)/ iv=(p1+p2+…+pi)/i <= w,这样做能比较有效地避免误差。
#include<bits/stdc++.h>//µΘΜε»ύ
using namespace std;
double p[110];
int main()
{
int t, n, v, w, i;
scanf("%d", &t);
while (t--){
scanf("%d%d%d", &n, &v, &w);
for (i = 0; i < n; i++)
scanf("%lf", &p[i]);
sort(p, p + n);
if (p[0] > w) printf("0 0.00\n");//排序后,浓度只能变大不能变小
else{
double tempp = p[0];
int tempv = v;
for (i = 1; i < n; i++){
tempp += p[i];
if (tempp / (i + 1) <= w) tempv += v;
else{
tempp -= p[i];
break;
}
}
printf("%d %.2lf\n", tempv, tempp / i / 100);
}
}
}
G.找零钱
#include<bits/stdc++.h>
using namespace std;
int a[10] = {50, 20, 10, 5, 1};
int b[10];
int main()
{
int n, i;
while (~scanf("%d", &n)){
for (i = 0; i < 5; i++){
b[i] = n / a[i];
n %= a[i];
}
int p = 0;
for (i = 0; i < 5; i++){
if (b[i]){
if (p) printf("+");
printf("%d*%d", a[i], b[i]);
p++;
}
}
printf("\n");
}
}