本题很简单,但是还是WA了几次,主要原因是
1、变量初始化的位置要非常小心,何时需要在下一次循环重复记录何时初始化,由于这个原因WA太可惜了
2、输出保留三位小数的格式控制一定要注意
主要算法思想如下
先求各个设备最小带宽中的最小值和最大带宽中的最小值
然后遍历最小带宽到最大带宽的区间,求最大比例,贪心搜索最优方案
加速方案
设置标志数组flag,只有输入中间出现过的并且位于上下界区间中带宽值才会考虑,节省搜索时间,空间换时间
另外总结下查看数据类型表示范围的方法,以int为例
1, 要看int 占用多少字节: sizeof(int)
2, 要看int 占用多少bits: sizeof(int) * 8
3, 要看int 所能表示的最大正整数: (unsigned int)(-1) / 2
输出格式精度控制 %m.ns 及%m.nd举例
第一个m表示输出字符串的长度,n表示从左边数第n位开始对齐
第二个m表示输出十进制数的位数,n表示小数点后的位数
比如24.1234
如果以%5.2d输出为24.12
Source Code
Problem: 1018 | User: yangliuACMer | |
Memory: 460K | Time: 47MS | |
Language: C++ | Result: Accepted |
#include <iostream>
using namespace std;
#define MAXN 32767
//先求各个设备最小带宽中的最小值和最大带宽中的最小值
//然后遍历最小带宽到最大带宽的区间,求最大比例,贪心搜索最优方案
int main(){
int t,n,sump,maxb,minb,minp,i,j,k,low,high;
int b[101][101],p[101][101],m[101],flag[MAXN];
double best;
cin>>t;
while(t--){
memset(flag, 0, sizeof(flag));
cin>>n;
low = high = MAXN;
for(i = 0; i < n; i++){
maxb = 0;
minb = MAXN;//变量初始化的位置要非常小心,何时需要在下一次循环重复记录何时初始化
cin>>m[i];
for(j = 0; j < m[i]; j++){
cin>>b[i][j]>>p[i][j];
flag[b[i][j]] = true;
if(b[i][j] < minb) minb = b[i][j] ;
if(b[i][j] > maxb) maxb = b[i][j] ;
}
if(low > minb)//各个设备最小带宽中的最小值
low = minb;
if(high > maxb)//各个设备最大带宽中的最小值
high = maxb;
}
best = 0;
for(k = low; k <= high; k++){
if(flag[k]){//只有输入中间出现过的并且位于上下界区间中带宽值才会考虑,节省搜索时间,空间换时间
sump = 0;
for(i = 0; i < n; i++){
minp = MAXN;
for(j = 0; j < m[i]; j++){
if(b[i][j] >= k && p[i][j] < minp){
minp = p[i][j];
}
}
sump += minp;
}
if((double)k / (double)sump > best){
best = (double)k / (double)sump;
}
}
}
printf("%.3lf\n",best);//保留3位小数
}
return 0;
}