快排大法好。
/**************************************************
**文件名:百炼-2795
**Copyright (c) 2010-2020 OrdinaryCrazy
**创建人:OrdinaryCrazy
**日期:20170803
**描述:百炼-2795参考答案
**版本:1.0
***************************************************/
#include <stdio.h>
#include <stdlib.h>
/*********
很直观的解决办法就是我们先找性价比高的金属装
所以这道题的关键在于对单价快速排序
*********/
int times,kind,carry;
double cost;
struct metrial
{
int weight;
int cost;
double unit;
}metrials[100];
typedef struct metrial metrial;
void swap(metrial*a,metrial*b)
{
metrial tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
/****************************************
**函数名:qs
**输入:l-需要排序的左侧起始索引
** r-需要排序的右侧起始索引
**功能:将l-r区间内的metrial结构变量按照单价由高到低排序
**作者:OrdinaryCrazy
**日期:20170803
**版本:1.0
*****************************************/
void qs(int l,int r)
{
if(l>r) return;
int i = l,j = r;
double x = metrials[l].unit;
while(i < j)
{
while(metrials[j].unit <= x&&i<j)j--;//从右边找一个比基准数大的数
while(metrials[i].unit >= x&&i<j)i++;//从左边找一个比基准数小的数
if(i<j) swap(&metrials[i],&metrials[j]);//还没有找到基准数归位的位置
}//应该说到这里i和j应该是已经相遇了,即i=j找到了基准数归位的位置
swap(&metrials[j],&metrials[l]);
qs(l,j-1);
qs(i+1,r);
}
int main()
{
int i,j;
scanf("%d",×);
for(i = 0;i < times;i++)
{
scanf("%d%d",&carry,&kind);
for(j = 0;j < kind;j++)
{
scanf("%d%d",&metrials[j].weight,&metrials[j].cost);
metrials[j].unit = (double)metrials[j].cost / (double)metrials[j].weight;
}
qs(0,kind - 1);
cost = 0;
for(j = 0;carry;j++)
{
if(carry >= metrials[j].weight)
{
cost +=metrials[j].cost;
carry -=metrials[j].weight;
}
else
{
cost += carry*metrials[j].unit;
carry = 0;
}
}
printf("%.2f\n",cost);
}
return 0;
}