目录:
&1:平均成绩
&2:套餐设计
&3:分班
例1:平均成绩
思路:……水题。But 注意用浮点数类型 否则除法损失精度
代码:
#include<iostream>
using namespace std;
int main()//acw-145-a
{
float a,b,c;
cin>>a>>b>>c;
if(((a+b+c)/3)>60) cout<<"YES";
else cout<<"NO";
return 0;
}
例2:套餐设计
思路:不知道大家写这题是什么感受,我是觉得这题就差把二分答案糊题上了(捂脸)
我们先对题目分析一波:
ai表示种类i从0到100的个数,与题目所给不一样
因为c/c++整型除法是向下取整的
又因为t是固定的
所有对每个样例有上图所给公式
因为ai和n都是固定的,我们只需要二分枚举答案即可也即二分答案
题目所求是最大,最大?->右逼近
不懂的小伙伴可以看看这篇文章(狗头)
所以有代码:
#include<iostream>
using namespace std;
int a[105];
int main()//145-b
{
int n, m, i, x, sum;
cin >> n >> m;
for (i = 0; i < m; i++)
{
cin >> x;
a[x]++;
}
int l = 0, r = m / n, mid;
while (l < r)
{
mid = (l + r + 1) >> 1, sum = 0;
for (i = 0; i < 105; i++) sum += a[i] / mid;
if (sum >= n) l = mid;
else r = mid - 1;
}
cout << l;
return 0;
}
例3:分班
思路:因为任意两个班的讲课速度都不能超过l
所以我们只需要通过确定 学习能力最差的学生 到 学习能力为最差生+l 间的学生个数cnt即可判定是否有答案
根据题目要求为了使讲课速度最大,然而又因为 任意两个班的讲课速度都不能超过l
所以我们要在这cnt个学生里,尽可能多挑选学习能力相对强的作为“班底”
我们可以先对这cnt个学生的学习能力排序
然后再这cnt个学生里把学习能力相对差的塞到一起(被塞的学生打0,相当于去除,这个时候fcnt--),满k后再开新班(即下图1到图2的过程)
这是这一过程的代码解释:
while (fcnt > n)
{
while (com < k)
{
b[i] = 0, fcnt--;
if (fcnt == n) break;
com++, i++;
}
com = 1, i++;
}
当fcnt==n时就是答案
至于 学习能力大于l 的人不用管,不论怎么塞都不影响结果
代码:
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
ll sum, cnt,a[100005], b[100005], fmin=2e9;
int main()//145-c
{
int n, m, k, l, i;
cin >> n >> k >> l;
m = n * k;
for (i = 0; i < m; i++)
{
cin >> a[i];
fmin = min(fmin, a[i]);
}
for (i = 0; i < m; i++)
{
if (a[i] <= (fmin + l))
{
b[cnt] = a[i];
cnt++;
}
}
if (cnt < n) cout << "0";
else
{
sort(b,b+cnt);
ll com = 1, i = 1, fcnt = cnt;
while (fcnt > n)
{
while (com < k)
{
b[i] = 0, fcnt--;
if (fcnt == n) break;
com++, i++;
}
com = 1, i++;
}
for (i = 0; i < cnt; i++) sum += b[i];
cout << sum;
}
return 0;
}
ps:
一开始我是用vector写的,但是tle了
while (b.size() > n)
{
while (com < k)
{
b.erase(b.begin() + i);
if (b.size() == n) break;
com++;
}
com = 1, i++;
}
原因是erase的时间复杂度是o(n)