10分求助,只对了第二个数据,求各位大佬帮忙看看,谢谢
查看原帖
10分求助,只对了第二个数据,求各位大佬帮忙看看,谢谢
176706
crystallee楼主2023/5/16 17:11

在此思路上,实在是不知道怎么改才正确,求各位大佬指点

//P3853 [TJOI2007]路标设置
#include <bits/stdc++.h>
using namespace std;
int n,k,a[100005],len,maxn=0;

int main(){
	cin>>len>>n>>k;
	for (int i=1;i<=n;i++){
		cin>>a[i];//读入已有的路标位置 
		if ((a[i]-a[i-1])>maxn) maxn=a[i]-a[i-1];//找出相邻路标的最大距离 
	}
	if (k==0){//如果k=0,表示不能增设路标,那么空旷指数就是最大距离maxn 
		cout<<maxn<<endl;
		return 0;//结束程序 
	}
	int l=1,r=len;//确定二分查找的左右端点
	while (l<r){//开始二分查找 
		int mid=l+(r-l)/2;//计算中间值
		int count=0;//初始化增设的路标数量为0
		int pre=0;//距离最近的上一个路标位置初始化为0 
		for (int i=2;i<=n;i++){	
			if ((a[i]-pre)<=mid){//否则第i个路标位置距离上一个路标没有超出现在的空旷指数mid,表示不需要增设路标 
				pre=a[i];//更新当前目标为最近的路标位置
			}
			else{
				while ((a[i]-pre)>mid){//如果 i个路标位置距离上一个路标超出现在的空旷指数mid,表示需要在此增设路标 
					count++;//路标数量+1 
					if (count>k) break;//如果增设的路标已经超过k了,直接跳出循环,节省时间 
					pre=pre+mid;//新设的路标并不一定在a[i]的位置,最远只能是上一个路标+mid的位置 
				}
				
			}
			if (count>k) break;//如果增设的路标已经超过k了,直接跳出循环,节省时间 
		} 
		if (count>k) l=mid+1;//如果增设路标超出k不能满足题意,表示空旷指数太小了,应该增大,在右半部分找,更新左端点 		
		else r=mid;//否则满足条件但可能还存在满足条件的更小值,在左半部分找,更新右端点 
	}
	cout<<r<<endl;//如果正常结束二分查找的循环,那最后l=r就是找到的答案,输出即可	
	return 0;
}
2023/5/16 17:11
加载中...