YBT P1243 GeBug日志
题目
【题目描述】
输入n个数,从小到大将它们输出,重复的数只输出一次。保证不同的数不超过500个。
【输入】
第一行是一个整数n。1≤n≤100000。
之后n行,每行一个整数。整数大小在int范围内。
【输出】
一行,从小到大不重复地输出这些数,相邻两个数之间用单个空格隔开。
【样例】
7 5
100
400
300
100
500
101
400
500
代码
int a[100099],m,n;
bool cmp(int x){
int ans = 1;
int tot = x;
for(int i = 1;i <= n; i++){
// cout << a[i] << ‘:‘ << tot << ‘:‘ << ans << endl ;
if(a[i] > x) return true;
if(tot >= a[i]){
tot -= a[i];
}
if(tot < a[i+1]){
tot = x;
ans++;
}
}
// cout << ans << endl;
return ans > m; ①
}
int main(){
cin >> n >> m;
int sum = 0;
int l = 0,r = sum,mid;
for(int i = 1;i <= n; i++){
cin >> a[i];
sum += a[i]; ②
l = max(a[i],l);
}
r = sum;
int ans;
while(r >= l){ ③
mid = (l + r) >> 1;
// cout << l << ‘ ‘ << r << ‘ ‘ << mid << endl;
if(cmp(mid)){
l = mid+1;
}else{
r = mid-1; ④
ans = mid; ⑤
}
}
// cout << l << ‘ ‘ << r << ‘ ‘ << mid << endl;
cout << ans << endl;
return 0;
}
DeBug
①:等号取不取的问题。
之前写的代码是 return ans >= m; 这里仔细思考一下。我的代码假设的是如果不符合要求就返回1,符合要求就返回0,那么 ans == m 很显然是符合条件的,如果也返回1,那就被算成错误的了。
②:左右端点的问题
其实这个地方比较无关紧要。右端点取总和,但是我的左端点一开始写的是取0,后来改成了a的最大值。其实我的cmp判断函数里面对这个东西有特判,所以这一句在DeBug的时候没啥用。
③④:返回条件的问题
二分模板掌握不熟练,打死好了。
⑤:答案记录的问题
只有mid的值返回0(也就是mid满足要求)的时候才能记录到ans,我之前不管返回几都记录,导致我答案不对。后来才放到else里面。
原文地址:https://www.cnblogs.com/Cao-Yucong/p/12562640.html
时间: 2024-10-24 09:44:12