目录

​问题 A: 看电视​

​代码A:​

​问题 B: 出租车费​

​代码B:​

​问题 C: To Fill or Not to Fill​

​代码C:​

​问题 D: Repair the Wall​

​代码D:​

​问题 E: FatMouse's Trade​

​代码E:​

​问题 F: 迷瘴​

​代码F:​

​问题 G: 找零钱​

​代码G:​


 

问题 A: 看电视

时间限制: 1 Sec  内存限制: 32 MB

题目描述

暑假到了,小明终于可以开心的看电视了。但是小明喜欢的节目太多了,他希望尽量多的看到完整的节目。
现在他把他喜欢的电视节目的转播时间表给你,你能帮他合理安排吗?

输入

输入包含多组测试数据。每组输入的第一行是一个整数n(n<=100),表示小明喜欢的节目的总数。
接下来n行,每行输入两个整数si和ei(1<=i<=n),表示第i个节目的开始和结束时间,为了简化问题,每个时间都用一个正整数表示。
当n=0时,输入结束。

输出

对于每组输入,输出能完整看到的电视节目的个数。

样例输入

12
1 3
3 4
0 7
3 8
15 19
15 20
10 15
8 18
6 12
5 10
4 14
2 9
0

样例输出

5

典型的区间贪心问题

代码A:

#include<iostream>    
#include<algorithm>
using namespace std;
struct TV
{
int s,e;//起始结束时间
}tv[110];

bool cmp(TV a,TV b){
if(a.s!=b.s) return a.s>b.s;
return a.e<b.e;
}
int main(){
int n;
while(cin>>n&&n!=0){
for(int i=0;i<n;i++){
cin>>tv[i].s>>tv[i].e;
}
sort(tv,tv+n,cmp);
int ans=1,lasts=tv[0].s;
for(int i=1;i<n;i++){
if(tv[i].e<=lasts){
lasts=tv[i].s;
ans++;
}
}
cout<<ans<<endl;
}
return 0;
}

 

问题 B: 出租车费

时间限制: 1 Sec  内存限制: 32 MB

题目描述

某市出租车计价规则如下:起步4公里10元,即使你的行程没超过4公里;接下来的4公里,每公里2元;之后每公里2.4元。行程的最后一段即使不到1公里,也当作1公里计费。
一个乘客可以根据行程公里数合理安排坐车方式来使自己的打车费最小。
例如,整个行程为16公里,乘客应该将行程分成长度相同的两部分,每部分花费18元,总共花费36元。如果坐出租车一次走完全程要花费37.2元。
现在给你整个行程的公里数,请你计算坐出租车的最小花费。

 

输入

输入包含多组测试数据。每组输入一个正整数n(n<10000000),表示整个行程的公里数。
当n=0时,输入结束。

输出

对于每组输入,输出最小花费。如果需要的话,保留一位小数。

样例输入

3
9
16
0

样例输出

10
20.4
36

注意:cout输出 数字大了会自动转换为科学计数法 而有时题目并不允许用科学计数法表示,导致一直答案错误。。。改用printf才行

代码B:

#include<iostream>
#include<cmath>
using namespace std;
int main(){ double n;
while(cin>>n&&n!=0){
double sum=0;
if(n<=4){
sum=10;
}else if(n<=8){
sum=10+2*ceil(n-4);
}else{
int x1=floor(n/8)*8;
sum=x1*2.25;
//接下来6公里时从头坐平均费用2.333<2.4 7公里平均2.285<2.4
int x2=ceil(n-x1);
if(x2==8) sum+=18;
else if(x2==7) sum+=16;
else if(x2==6) sum+=14;
else sum+=2.4*x2;
}
if(sum-int(sum)!=0)
printf("%.1f\n",sum);
else printf("%.0f\n",sum);
//用cout大了会自动用科学计数法 而题目为让用科学计数法 所以一直错误 最好用printf()
}
return 0;
}

 

 

问题 C: To Fill or Not to Fill

时间限制: 1 Sec  内存限制: 32 MB

题目描述

With highways available, driving a car from Hangzhou to any other city is easy. But since the tank capacity of a car is limited, we have to find gas stations on the way from time to time. Different gas station may give different price. You are asked to carefully design the cheapest route to go.

输入

Each input file contains one test case. For each case, the first line contains 4 positive numbers: Cmax (<= 100), the maximum capacity of the tank; D (<=30000), the distance between Hangzhou and the destination city; Davg (<=20), the average distance per unit gas that the car can run; and N (<= 500), the total number of gas stations. Then N lines follow, each contains a pair of non-negative numbers: Pi, the unit gas price, and Di (<=D), the distance between this station and Hangzhou, for i=1,...N. All the numbers in a line are separated by a space.

输出

For each test case, print the cheapest price in a line, accurate up to 2 decimal places. It is assumed that the tank is empty at the beginning. If it is impossible to reach the destination, print "The maximum travel distance = X" where X is the maximum possible distance the car can run, accurate up to 2 decimal places.

样例输入

59 525 19 2
3.00 314
3.00 0

样例输出

82.89

提示

该题目所要解决的问题是:给定若干加油站信息,问能否驾驶汽车行驶一定的距离。如果能够行驶完全程,则计算最小花费。若不能行驶完全程,则最远能够行驶多长距离。

拿到这一题,首先判断汽车是否能够行驶到终点。什么情况下汽车无法行驶到终点呢?两种情况:起点根本就没有加油站,汽车无法启动;或者中途两个加油站之间的距离大于加满油后汽车能够行驶的最大距离。前者汽车行驶的最大距离为0.00,而后者最大距离为当前加油站的距离加上在这个加油站加满油后能够行驶的最大距离。在这里,需要将加油站按到杭州的距离从小到大排序。

接下来在能够行驶到终点的情况下计算最小花费。我们首先从路程来考虑,如果在路上,我们能够使用最便宜的汽油,当然就在那个加油站加油了。所以从起点开始遍历每个加油站。假设遍历到了第i个加油站,我们现在来判断在加油站i应该加多少油。设当前汽车离杭州的距离为curLen,当前加油站离杭州的距离为nodes[i].dis,加满油以后汽车能够行驶的最大距离为(dis=cmax*len)。这样就有node[i].dis <= curLen <= nodes[i].dis+dis,否则的话第i个加油站的油是不起作用的。于是在第i个加油站的作用范围内寻找有没有更为便宜的加油站,如果有,则下次使用这个加油站的油(j),这次汽车应该行驶到这个加油站,即touch=nodes[j].dis。如果没有找到更为便宜的加油站则可以在第i个加油站加满油,即touch=nodes[i].dis+dis。然后判断下次应该行驶到的距离与当前距离的关系,如果下次应当行驶到的距离大于当前距离,则汽车行驶,否则不动(也就是说上个加油站的油更便宜,后一个加油站也便宜,根本就不需要在当前加油站加油)。

 

注意1:一路向前,不存在后退,公路上行走的轨迹长度为路程,高速公路每隔一点路程就有加油站,但看你怎么加
注意2:加油的价格=要加跑的距离/len*price

算法思路:
在自己的范围内遍历所有价格:
若自己的油价最低
若能直接到达终点
加油到终点即可
若不能直接到终点
加满

在自己范围内找到油价次低的
(油满状态下)开到油价次低的站点(有余油)

若自己的油价不是最低
找自己范围内离自己最近的比自己便宜的站点B
若余油能跑到B站点
跑到B站点(更新余油)
若余油不能跑到B站点
加油到能跑到B站点即可(余油变为0)

 

代码C:

#include<iostream>    
#include<algorithm>
#include<cmath>
using namespace std;
struct gas
{
double price;
double distance;
}Gas[510];
bool cmp(gas a,gas b){
if(a.distance!=b.distance) return a.distance<b.distance;//同一个地方应该不会有两个加油站 但还是写了
return a.price<b.price;
}
int main(){
double C,D,len;
int N;
while(cin>>C>>D>>len>>N){
for(int i=0;i<N;i++){
cin>>Gas[i].price>>Gas[i].distance;
}
sort(Gas,Gas+N,cmp);
if(Gas[0].distance>0){
cout<<"The maximum travel distance = 0"<<endl;
continue;
}
double least=D,money=0;//least剩余距离 money加油总价钱
double max=C*len;//加满油能跑的最远距离
double oil=0;//余油
//当前路程就是当前加油站离杭州的距离
for(int i=0;i<N;i++){
//最后一个加油站了
if(i==N-1){
//开不到
if(max<D-Gas[i].distance){
printf("The maximum travel distance = %.2f\n",Gas[i].distance+max);
break;//注意for外
}else{
//开得到
money+=Gas[i].price*((D-Gas[i].distance)/len-oil);
printf("%.2f\n",money);
break;
}
}
//加满也开不到下一个加油站
if(max<Gas[i+1].distance-Gas[i].distance){
printf("The maximum travel distance = %.2f\n",Gas[i].distance+max);
break;//注意for外
}
//一般情况
/**
先找到最近的比当前便宜的站 找不到再遍历找最小的
*/
least=D-Gas[i].distance;//当前剩余路程
int min=i;
for(int j=i+1;j<N;j++){
if((Gas[j].distance-Gas[i].distance)<=max && Gas[j].price<Gas[min].price){
min=j;
break;
}
}
if(min==i){//当前最便宜 接着找次便宜的
if(least<=max){//能直接开到了
money+=Gas[i].price*(least/len-oil);
printf("%.2f\n",money);
break;
}

min=i+1;
for(int j=i+2;j<N;j++){
if((Gas[j].distance-Gas[i].distance)<=max && Gas[j].price<Gas[min].price) min=j;
}

//自己最小,必须加满,但只开到次小,到时候油有余量 (开不到的前提下)
money+=Gas[i].price*(max/len-oil);//加满
oil=max/len-(Gas[min].distance-Gas[i].distance)/len;//剩余油量
i=min-1;//下次到min 循环体里还有i++
}else{
//当前不是最便宜的 不能多加
if(oil>=(Gas[min].distance-Gas[i].distance)/len){
//不用加 余下的油能直接开到
oil-=(Gas[min].distance-Gas[i].distance)/len;
i=min-1;//i的变化一定要在最后 因为i时刻要用
}else{
//余下的油开不到
money+=Gas[i].price*((Gas[min].distance-Gas[i].distance)/len-oil);
oil=0;//加到正好开完
i=min-1;
}
}
}
}
return 0;
}

 

问题 D: Repair the Wall

时间限制: 1 Sec  内存限制: 32 MB

题目描述

Long time ago , Kitty lived in a small village. The air was fresh and the scenery was very beautiful. The only thing that troubled her is the typhoon.

When the typhoon came, everything is terrible. It kept blowing and raining for a long time. And what made the situation worse was that all of Kitty's walls were made of wood.

One day, Kitty found that there was a crack in the wall. The shape of the crack is 
a rectangle with the size of 1×L (in inch). Luckly Kitty got N blocks and a saw(锯子) from her neighbors.
The shape of the blocks were rectangle too, and the width of all blocks were 1 inch. So, with the help of saw, Kitty could cut down some of the blocks(of course she could use it directly without cutting) and put them in the crack, and the wall may be repaired perfectly, without any gap.

Now, Kitty knew the size of each blocks, and wanted to use as fewer as possible of the blocks to repair the wall, could you help her ?

输入

The problem contains many test cases, please process to the end of file( EOF ).
Each test case contains two lines.
In the first line, there are two integers L(0<L<1000000000) and N(0<=N<600) which
mentioned above.
In the second line, there are N positive integers. The ith integer Ai(0<Ai<1000000000 ) means that the ith block has the size of 1×Ai (in inch).

输出

For each test case , print an integer which represents the minimal number of blocks are needed.
If Kitty could not repair the wall, just print "impossible" instead.

样例输入

2 2
12 11
14 3
27 11 4
109 5
38 15 6 21 32
5 3
1 1 1

样例输出

1
1
5
impossible

代码D:

#include<iostream>
#include<algorithm>
using namespace std;
bool cmp(int a,int b){
return a>b;
}
//分析 int类型足矣
int main(){
int L,N;
int len[610];
while(cin>>L>>N){
for(int i=0;i<N;i++)
cin>>len[i];
sort(len,len+N,cmp);
int sum=0;
int i;
for(i=0;i<N;i++){
sum+=len[i];
if(sum>=L) break;
}
if(i==N) cout<<"impossible\n";
else cout<<i+1<<endl;
}
return 0;
}

 

问题 E: FatMouse's Trade

时间限制: 1 Sec  内存限制: 32 MB

题目描述

FatMouse prepared M pounds of cat food, ready to trade with the cats guarding the warehouse containing his favorite food, JavaBean.
The warehouse has N rooms. The i-th room contains J[i] pounds of JavaBeans and requires F[i] pounds of cat food. FatMouse does not have to trade for all the JavaBeans in the room, instead, he may get J[i]* a% pounds of JavaBeans if he pays F[i]* a% pounds of cat food. Here a is a real number. Now he is assigning this homework to you: tell him the maximum amount of JavaBeans he can obtain. 

 

输入

The input consists of multiple test cases. Each test case begins with a line containing two non-negative integers M and N. Then N lines follow, each contains two non-negative integers J[i] and F[i] respectively. The last test case is followed by two -1's. All integers are not greater than 1000.

 

输出

For each test case, print in a single line a real number accurate up to 3 decimal places, which is the maximum amount of JavaBeans that FatMouse can obtain.

 

样例输入

4 2
4 7
1 3
5 5
4 8
3 8
1 2
2 5
2 4
-1 -1

样例输出

2.286
2.500

代码E:

#include<iostream>
#include<algorithm>
using namespace std;

struct Room
{
int j,f;
double price;
}room[1010];

bool cmp(Room a,Room b){
if(a.price!=b.price)
return a.price>b.price;
return a.j>b.j;
}

int main(){
int M,N;
while(cin>>M>>N){
if(M==-1) break;
for (int i = 0; i < N; ++i){
cin>>room[i].j>>room[i].f;
room[i].price=room[i].j*1.0/room[i].f;
}
sort(room,room+N,cmp);
double sum=0;
for(int i=0;i<N;i++){
if(M>=room[i].f){
M-=room[i].f;
sum+=room[i].j;
}else{
sum+=room[i].price*M;
break;
}
}
printf("%.3f\n",sum);
}
return 0;
}

 

 

问题 F: 迷瘴

时间限制: 1 Sec  内存限制: 32 MB

题目描述

小明正在玩游戏,他控制的角色正面临着幽谷的考验——
幽谷周围瘴气弥漫,静的可怕,隐约可见地上堆满了骷髅。由于此处长年不见天日,导致空气中布满了毒素,一旦吸入体内,便会全身溃烂而死。
幸好小明早有防备,提前备好了解药材料(各种浓度的万能药水)。现在只需按照配置成不同比例的浓度。
现已知小明随身携带有n种浓度的万能药水,体积V都相同,浓度则分别为Pi%。并且知道,针对当时幽谷的瘴气情况,只需选择部分或者全部的万能药水,然后配置出浓度不大于 W%的药水即可解毒。
现在的问题是:如何配置此药,能得到最大体积的当前可用的解药呢?
特别说明:由于幽谷内设备的限制,只允许把一种已有的药全部混入另一种之中(即:不能出现对一种药只取它的一部分这样的操作)。

输入

输入数据的第一行是一个整数C,表示测试数据的组数;
每组测试数据包含2行,首先一行给出三个正整数n,V,W(1<=n,V,W<=100);
接着一行是n个整数,表示n种药水的浓度Pi%(1<=Pi<=100)。

输出

对于每组测试数据,请输出一个整数和一个浮点数;
其中整数表示解药的最大体积,浮点数表示解药的浓度(四舍五入保留2位小数);
如果不能配出满足要求的的解药,则请输出0 0.00。

样例输入

2
1 35 68
1
2 79 25
59 63

样例输出

35 0.01
0 0.00

代码F:

#include<iostream>
#include<algorithm>
using namespace std;
int pi[110];
double avg(int n){
int sum=0;
for(int i=0;i<=n;i++){
sum+=pi[i];
}
return sum*1.0/(n+1);
}
//四舍五入 2为小数
double fouFive(double n){
return int(n*100+0.5)/100.0;//强转给你去尾了
}

int main(){
int c,n,v,w;
cin>>c;
while(c--){
cin>>n>>v>>w;
for(int i=0;i<n;i++){
cin>>pi[i];
}
sort(pi,pi+n);
int index=0;
//找到第一大于w的浓度
while(pi[index]<=w&&index<n){
index++;
}
//浓度都小于100并入最最后处理了 index=n
//浓度都大于w
if(index==0){
cout<<"0 0.00"<<endl;
continue;
}
int i=index;
for(i=index;i<n;i++){
if(avg(i)>w){
printf("%d %.2f\n",i*v,fouFive(avg(i-1)/100.0));//之前i竟然错写成index了...
break;
}
}
if(i==n){
printf("%d %.2f\n",n*v,fouFive(avg(n-1)/100.0));
}
}
return 0;
}

 

 

问题 G: 找零钱

时间限制: 1 Sec  内存限制: 128 MB
提交: 148  解决: 106
[​​​提交​​​][​​状态​​​][​​讨论版​​][命题人:外部导入]

题目描述

小智去超市买东西,买了不超过一百块的东西。收银员想尽量用少的纸币来找钱。
纸币面额分为50 20 10 5 1 五种。请在知道要找多少钱n给小明的情况下,输出纸币数量最少的方案。 1<=n<=99;

输入

有多组数据  1<=n<=99;

输出

对于每种数量不为0的纸币,输出他们的面值*数量,再加起来输出

样例输入

25
32

样例输出

20*1+5*1
20*1+10*1+1*2

代码G:

#include<iostream>
using namespace std;
int a[]={50,20,10,5,1};

int main(){
int n;
while(cin>>n){
int b[5]={0};
bool flag=true;
for (int i = 0; i < 5&&n>0; ++i)
{
if(n>=a[i]){
b[i]=n/a[i];
if(b[i]){
if(flag) {
cout<<a[i]<<"*"<<b[i];
flag=false;
}else{
cout<<"+"<<a[i]<<"*"<<b[i];
}
}
n=n%a[i];
}
}
cout<<endl;
}
return 0;
}