题目一:(典型题目)
购买商品
有m元钱,n种物品;每种物品有j磅,总价值f元。(可以使用0.3f购买0.3j物品)
输入:M,N 以及N 种物品的重量和总价格
输出:最多能买到多少磅物品
思路:每次购买剩余物品中性价比最高的物品
代码:
#define _CRT_SECURE_NO_DEPRECATE
/*
贪心算法:购买最多的商品
*/
#include<stdio.h>
#include<algorithm>
using namespace std;
struct goods {
double j;//物品总重
double f;//物品总价值
double s;//单价
bool operator < (const goods &A) const
{
return s < A.s; //升序排列
}
}buf[1000];
int main()
{
int m, n;
while (scanf("%d%d", &m, &n) != EOF)
{
if (m == -1 && n == -1)
break;
for (int i = 0; i < n; i++)
{
scanf("%lf%lf", &buf[i].j, &buf[i].f);
buf[i].s = buf[i].f / buf[i].j;
}
sort(buf, buf + n);
//有钱并且物品还有
int index = 0;
double res = 0;
while (index < n && m>0)
{
if (buf[index].f <= m)
{
res += buf[index].j;
m -= buf[index].f;
}
else
{
res += buf[index].j*m / buf[index].f;
m = 0;
}
index++;
}
printf("%.3lf\n", res);
}
return 0;
}
题目二(典型)
看电视节目
输入:N(节目总数),N行节目的开始时间和结束时间
输出:能完整看到的节目个数
解题思路:
优先选择结束时间最早的节目:原因如果最优解的第一个节目不是结束最早的节目,那么我们可以使用一个结束早的来替换,替换后的解是一样的
在选择第x个节目的时候,我们选择在x-1个节目结束的时候,其他所有可以收看的节目结束时间最早的节目
代码:
#define _CRT_SECURE_NO_DEPRECATE
/*
贪心算法:可以看到电视节目总数
*/
#include<stdio.h>
#include<algorithm>
using namespace std;
struct program {
int startTime;
int endTime;
bool operator < (const program &A) const {
return endTime < A.endTime;
}
}buf[100];
int main()
{
int n;
while (scanf("%d", &n) != EOF)
{
if (n == 0) break;
for (int i = 0; i < n; i++)
{
scanf("%d%d", &buf[i].startTime, &buf[i].endTime);
}
sort(buf, buf + n);
//对排序后的节目进行遍历
int currentTime = 0;
int res = 0;
for (int i = 0; i < n; i++)
{
if (currentTime <= buf[i].startTime)
{
currentTime = buf[i].endTime;
res += 1;
}
}
printf("%d\n", res);
}
return 0;
}
题目三:
迷障
n种浓度的万能药水,体积V都相同,浓度则分别为Pi%,配置出浓度不大于 W%的药水—得到最大体积
输入:
一个整数C,表示测试数据的组数(输入方式)
每组测试数据包含2行,首先一行给出三个正整数n,V,W(1<=n,V,W<=100);
接着一行是n个整数,表示n种药水的浓度Pi%(1<=Pi<=100)。
输出:
对于每组测试数据,请输出一个整数和一个浮点数;
其中整数表示解药的最大体积,浮点数表示解药的浓度(四舍五入保留2位小数);
如果不能配出满足要求的的解药,则请输出0 0.00
思路:
选取浓度最低的来配置,体积相同
混合液体的浓度 = (浓度和)/n
代码:
#define _CRT_SECURE_NO_DEPRECATE
/*
贪心算法:配置药水 (a+b)/2
*/
#include<stdio.h>
#include<algorithm>
using namespace std;
int main()
{
int C;
scanf("%d", &C);
while (C-->0)
{
int n, v, w;
int p[100] = {0};
scanf("%d%d%d", &n, &v, &w);
for (int i = 0; i < n; i++)
{
scanf("%d", &p[i]);
}
sort(p, p + n);
int curP = 0; //当前浓度
int curV = 0; //当前体积个数
for (int i = 0; i < n; i++)
{
//由于浓度可能是double类型的数据,判断起来容易出错,所以我们反向思考,将除以改成乘以
if ((curP + p[i]) <= w*(curV+1))
{
curP +=p[i];
curV+=1;
}
else
{
break;
}
}
if (curV == 0)
printf("0 0.00\n");
else
printf("%d %.2lf\n", curV*v, curP*1.0/(100*curV)); //这里要用小数表示,所以要除以(100*curV)
}
return 0;
}
题目四:
修理墙壁–使用尽可能小的木板
The shape of the crack is a rectangle with the size of 1×L (in inch)
the width of all blocks were 1 inch.
样例输入:
5 3
3 2 1
5 2
2 1
样例输出:
2
impossible
代码:
#define _CRT_SECURE_NO_DEPRECATE
#include<stdio.h>
#include<algorithm>
using namespace std;
bool cmp(int a, int b)
{
return a > b;
}
int main()
{
int L,n;
int buf[601];
while (scanf("%d%d", &L,&n) != EOF)
{
for (int i = 0; i < n; i++)
{
scanf("%d", &buf[i]);
}
sort(buf, buf + n,cmp);//降序排列
int current = 0;
int res = 0;
for (int i = 0; i < n; i++)
{
if (current < L)
{
current += buf[i];
res += 1;
}
else
{
break;
}
}
if (current < L)
printf("impossible\n");
else
printf("%d\n", res);
}
return 0;
}
题目五: