本题很简单,但是还是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; }