记录39
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,a[55]={},s=0,L,R,t1=0,t2=0;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
s+=a[i];
}
cin>>L>>R;
double x=s*1.0/n;
if(x<L||x>R){
cout<<-1;
return 0;
}
for(int i=1;i<=n;i++){
if(a[i]<L) t1+=L-a[i];
if(a[i]>R) t2+=a[i]-R;
}
cout<<max(t1,t2);
return 0;
}
题目传送门
https://www.luogu.com.cn/problem/P1109
突破点
每次你可以在某组中选出一个学生把他安排到另外一组中,问最少要多少次才可以使 N 组学生的人数都在 [L,R] 中
思路
- 判断可不可以分
- 实现最小交换次数,肯定是解决低于边界或者高于边界中,二者大的那个
例如:
组数:5
每组人数:A组:8 B组:20 C组:14 D组:13 E组:15
上下边界:最少:10 最多:15A组少了两个人,B组多了5个人
最小满足区间范围交换人数,肯定是处理掉多出来的5个人
将多出来的人给补到A组里面,然后再每组随便分多的人
无论放在哪一组,处理的都是不满足边界的人数的情况
代码简析
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,a[55]={},s=0,L,R,t1=0,t2=0;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
s+=a[i];
}
...
}
a[55]={} 数组a代表每组的人数
t1=0,t2=0; 其中t1代表少的下界人数,t2代表多出来的上界限人数
s=0; 将所有组数的人加到s里面
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,a[55]={},s=0,L,R,t1=0,t2=0;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
s+=a[i];
}
cin>>L>>R;
double x=s*1.0/n;
if(x<L||x>R){
cout<<-1;
return 0;
}
for(int i=1;i<=n;i++){
if(a[i]<L) t1+=L-a[i];
if(a[i]>R) t2+=a[i]-R;
}
cout<<max(t1,t2);
return 0;
}
double x=s*1.0/n; 组数人数和平均分不一定是刚好均分的整数,所以s*1.0,并且x是double类型
if(x<L||x>R){} x均分后不满足情况,说明无论如何都满足不了条件
if(a[i]<L) t1+=L-a[i]; 存下来每组小于边界的人数
if(a[i]>R) t2+=a[i]-R; 存下来每组大于边界的人数
cout<<max(t1,t2); 二者进行比较,取其中大的人数,介绍转至思路的例子
补充
C++ 整数与浮点数类型转换完全指南
1. 核心机制:隐式类型转换规则
当整数与浮点数运算时,C++自动将整数提升为浮点类型(类型提升)。
int a = 5; double b = a * 1.0; // a先转为double,再乘以1.0 // 等价于:double b = static_cast<double>(a) * 1.0;转换优先级:
int→long long→float→double→long double
2. 转换场景与精度问题
场景A:int → float
int a = 123456789; float f = a * 1.0f; // 或 (float)a // 问题:float仅6-7位有效数字,可能丢失精度 // f = 123456792.0 (后几位不准确)结论:当
int > 2^24 (约1670万)时,转float可能精度丢失。场景B:int → double
int a = 123456789; double d = a * 1.0; // 推荐 // double有15-16位有效数字,完全保留int范围(-2^31~2^31-1)结论:
int转double安全,无精度损失。场景C:long long → double
long long ll = 1e18; double d = ll * 1.0; // 问题:double约15位有效数字,1e18有19位,可能丢失低位结论:当
long long > 2^53 (约9e15)时,转double会精度丢失。
3. 整数除法陷阱与修复
错误:整数除法
int a = 5, b = 2; double c = a / b; // 结果:c = 2.0(不是2.5!) // 原因:先进行整数除法得到2,再转为double正确:转换为浮点再除
// 方法1:乘1.0(竞赛最常用) double c1 = a * 1.0 / b; // 5.0/2 = 2.5 // 方法2:显式转换 double c2 = double(a) / b; double c3 = (double)a / b; // 方法3:使用static_cast double c4 = static_cast<double>(a) / b;
4. 类型转换大小等级
// 从小到大自动转换(安全) char → short → int → long long → float → double → long double // 从大向小需要强制转换(可能溢出/丢失精度) double → int // 截断小数,非四舍五入截断示例
double d = 3.99; int a = d; // a = 3(直接截断,不是4!) // 要四舍五入需用:int a = d + 0.5;
5. 竞赛高频使用场景
场景1:计算平均值
int sum = 15, cnt = 4; double avg = sum * 1.0 / cnt; // 3.75 避免整数除法场景2:防止中间乘积溢出
int a = 1e9, b = 1e9; long long c = a * 1LL * b; // 先转long long再乘,避免int溢出 // 错误:long long c = a * b; // 先int溢出,再转long long场景3:比较浮点数
double a = 0.1 * 3; double b = 0.3; // 错误:if (a == b) // 可能因精度问题不相等 // 正确:使用eps const double EPS = 1e-9; if (fabs(a - b) < EPS) { // 认为相等 // ... }
6. 性能与开销
转换类型 性能影响 原因 int → double极小 CPU硬件原生支持,单指令完成 long long → double较小 可能需要多周期,但可忽略 double → int中等 需要截断指令,约3-5个时钟周期 多次转换 累计 在循环中应减少重复转换 竞赛建议:无需过度优化类型转换,正确性优先。
7. 显式转换 vs 隐式转换
int a = 5; double b; // 隐式转换(不推荐,可能隐藏警告) b = a; // 自动转换,可能产生编译警告 // 显式转换(推荐,代码意图明确) b = static_cast<double>(a); // C++风格,最规范 b = (double)a; // C风格,兼容性好 b = a * 1.0; // 竞赛常用,简洁
8. 常见错误与调试技巧
错误1:忘记转换导致整数除法
// 错误代码 int a = 5, b = 2; cout << a / b; // 输出2 // 修复 cout << a * 1.0 / b; // 输出2.5错误2:转换时机错误
int a = 5, b = 2; double c = (double)(a / b); // 错误:先整数除法得2,再转2.0 double d = (double)a / b; // 正确:a先转5.0,再除得2.5错误3:精度丢失未察觉
int n = 2000000000; // 2e9 float f = n; // 精度丢失,可能变成1999999872 cout << f; // 输出错误结果 // 解决:用double
9. CSP竞赛最佳实践
// 模板1:安全除法 inline double safe_div(int a, int b) { return a * 1.0 / b; } // 模板2:防溢出乘法 inline long long safe_mul(int a, int b) { return a * 1LL * b; } // 模板3:浮点数比较 inline bool double_equal(double a, double b) { const double EPS = 1e-9; return fabs(a - b) < EPS; } // 主代码 int main() { int a, b; cin >> a >> b; // ✅ 正确姿势 double avg = a * 1.0 / b; long long product = a * 1LL * b; // ✅ 四舍五入 int rounded = avg + 0.5; return 0; }
10. 核心要点速查表
需求 推荐写法 结果/注意事项 整数→浮点除法 a * 1.0 / b得到精确小数结果 int→double int * 1.0安全,无精度损失 int→float int * 1.0f大数可能精度丢失 防溢出 a * 1LL * ba和b先转long long 四舍五入 int(d + 0.5)不是强制转换 double→int (int)d截断,非四舍五入 浮点相等判断 fabs(a-b) < EPS避免直接用 ==终极建议:在CSP中,记住
*1.0和*1LL两个技巧,可解决90%的类型转换问题。精度问题一律用double,避免使用float。
590

被折叠的 条评论
为什么被折叠?



