九度1435 迷瘴
-
题目描述:
-
通过悬崖的yifenfei,又面临着幽谷的考验——
幽谷周围瘴气弥漫,静的可怕,隐约可见地上堆满了骷髅。由于此处长年不见天日,导致空气中布满了毒素,一旦吸入体内,便会全身溃烂而死。
幸好yifenfei早有防备,提前备好了解药材料(各种浓度的万能药水)。现在只需按照配置成不同比例的浓度。
现已知yifenfei随身携带有n种浓度的万能药水,体积V都相同,浓度则分别为Pi%。并且知道,针对当时幽谷的瘴气情况,只需选择部分或者全部的万能药水,然后配置出浓度不大于 W%的药水即可解毒。
现在的问题是:如何配置此药,能得到最大体积的当前可用的解药呢?
特别说明:由于幽谷内设备的限制,只允许把一种已有的药全部混入另一种之中(即:不能出现对一种药只取它的一部分这样的操作)。
-
输入:
-
输入数据的第一行是一个整数C,表示测试数据的组数;
每组测试数据包含2行,首先一行给出三个正整数n,V,W(1<=n,V,W<=100);
接着一行是n个整数,表示n种药水的浓度Pi%(1<=Pi<=100)。
-
输出:
-
对于每组测试数据,请输出一个整数和一个浮点数;
其中整数表示解药的最大体积,浮点数表示解药的浓度(四舍五入保留2位小数);
如果不能配出满足要求的的解药,则请输出0 0.00。
-
样例输入:
-
3 1 100 10 100 2 100 24 20 30 3 100 24 20 20 30
-
样例输出:
-
0 0.00 100 0.20 300 0.23
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
bool cmp(double a,double b)
{return a<b;}
int main(int argc, char* argv[])
{
int c;
while(scanf("%d",&c)!=EOF)
{
while(c--)
{
int n,v,w; //n表示药水种类数 v表示每瓶的体积(每瓶体积相同) w表示所需最大浓度
double p[100]; //用数组来表示药水
scanf("%d %d %d",&n,&v,&w);
int i;
for(i=0;i<n;i++)
{
scanf("%lf",&p[i]);
}
sort(p,p+n,cmp); //按照药水浓度升序排列
int maxV=0;
double maxP=0;
double sum=0;
double currentP=0;
i=0;
while(i<n)
{
sum=sum+p[i];
currentP=(sum)/(i+1);
if(currentP<=w){
maxV+=v;
maxP=currentP*0.01;
i++;
}
else{
break;
}
}
if(i==0) printf("0 0.00\n");
else printf("%d %.2lf\n",maxV,maxP);
}
}
return 0;
}
九度1436 Repair the Wall
-
题目描述:
-
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.
-
样例输入:
-
5 3 3 2 1 5 2 2 1
-
样例输出:
-
2 impossible
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
bool cmp(int a,int b)
{return a>b;}
int main(int argc, char* argv[])
{
int L,N;
while(scanf("%d %d",&L,&N)!=EOF)
{
int i;
int A[1000]; //定义每个block的大小
for(i=0;i<N;i++)
{
scanf("%d",&A[i]);
}
sort(A,A+N,cmp); //按照block大小降序排列
int currentL=0; //设置当前已经补充的长度
int min=0; //表示需要的block块数
i=0;
while(currentL<=L&&i<N){
if((L-currentL)>A[i]) //如果该block不够补充剩余裂缝,则继续使用下一block
{
currentL+=A[i];
min+=1;
i++;
}
else //如果该block足够补充剩余裂缝,则退出
{
currentL=L;
min+=1;
break;
}
}
if(currentL<L) printf("impossible\n");
else printf("%d\n",min);
}
return 0;
}
九度OJ 1437 To Fill or Not to Fill (浙大机试题 难!)
这道题我没做出来,以上是网上的代码点击打开链接//贪心算法 //dis=满油箱可以开出的最远距离。 //算法描述:起点A开始,到A+dis范围内: //1.如果存在点B的s[B].price<=s[A].price,只要满足能行驶到B点即可 //2.如果不存在点B的s[B].price<=s[A].price,则要使车能开到 A+dis范围内除A以外,price最小的点--min_index所指点 //注意: //1.终点如果在 A+dis范围内,一定可达 //2.注意排序后第一个点的dis可能不为0 //3.离A点最近的B点与A的距离如果>dis,则此趟行驶到不了终点 //4.油箱的情况每次都要关注 //具体见代码: #include<iostream> #include<queue> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; struct station{ double price,dis; }; station s[505]; bool cmp(station a,station b){ return a.dis<b.dis; } int main(){ double cmax,d,davg; int n; while(scanf("%lf%lf%lf%d",&cmax,&d,&davg,&n)!=EOF){ double min_price=0; double max_dis=0; double cur_tank=0; int i=0; for(;i<n;i++){ cin>>s[i].price>>s[i].dis; } s[i].dis=d; s[i].price=0; sort(s,s+n,cmp); /*for(i=0;i<=n;i++){ cout<<s[i].dis<<' '<<s[i].price<<endl; }*/ if(s[0].dis>0){//2.注意排序后第一个点的dis可能不为0 //cout<<1<<endl; printf("The maximum travel distance = 0.00\n"); continue; } int f=0; double dis=cmax*davg; int min_index; while(s[f].dis<d){ int next=f+1; min_index=next; while((s[next].dis-s[f].dis)<=dis){//如果next==n,一定会从break处出去 //跳出循环只有三种情况: //1.在dis范围内,没有点与f点的距离小于等于dis //2.在dis范围内,找到price小于f的点(包括next==n) //3.next!=n,但在dis范围内,没有找到price小于f的点。在dis范围内,有点与f点的距离小于等于dis if(s[next].price<s[min_index].price){//记录最小的油价的站点 min_index=next; } if(s[next].price<=s[f].price){//在dis范围内,找到price小于f的点 break; } next++; } if(next==f+1&&(s[next].dis-s[f].dis)>dis){//1.在dis范围内,没有点与f点的距离小于等于dis //cout<<1<<endl; max_dis+=dis; break; } else{ if((s[next].dis-s[f].dis)<=dis){//2.在dis范围内,找到price小于f的点(包括next==n) if(s[next].dis-s[f].dis>cur_tank){ min_price+=(s[next].dis-s[f].dis-cur_tank)*s[f].price; cur_tank=0; max_dis+=s[next].dis-s[f].dis; } else{ cur_tank-=s[next].dis-s[f].dis; max_dis+=s[next].dis-s[f].dis; } f=next; } else{//3.next!=n,但在dis范围内,没有找到price小于f的点。在dis范围内,有点与f点的距离小于等于dis min_price+=(dis-cur_tank)*s[f].price; cur_tank=dis-(s[min_index].dis-s[f].dis); max_dis+=s[min_index].dis-s[f].dis; f=min_index; } } } if(s[f].dis==d){ printf("%.2lf\n",min_price/davg); } else{ printf("The maximum travel distance = %.2lf\n",max_dis*1.0);//注意输出格式 } } return 0; }