大致题意:
坐标 从 [0-L], 上有 N 个点 , 现在需要移去 M 个点.求任意两点(包括0,L)点的距离中最小值的最大值
思路:枚举答案,若移去M个点不能达成目标,则使答案变小.
while(l <= r){ ll mid = l + (r-l)/2; // 是否可能使得所有石头之间的距离不小于 mid if(check(mid)){ l = mid+1; }else{ r = mid-1; } } printf("%lld\n",l-1);
1 bool check(ll mid){ 2 ll cnt = 0; 3 ll pre = 0; 4 for(ll i = 1 ; i <= N ; i ++){ 5 if(D[i]-D[pre]>=mid){ 6 pre = i; 7 }else{ //两块之间距离大于要求距离的话,移去该石头 8 cnt++; 9 } 10 if(cnt > M) return false; 11 } 12 return true; 13 }
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 5 #include<string> 6 #include<vector> 7 #include<set> 8 #include<map> 9 #include<queue> 10 #include<math.h> 11 12 #include<algorithm> 13 #include<iostream> 14 15 const int INF = 0x7f7f7f7f; 16 using namespace std; 17 typedef long long ll; 18 19 /* 20 1<=L<=100000000 21 N:rocks 22 M:remove rocks 23 Di: 24 L N M: 25 */ 26 27 ll D[50005]; 28 int L,N,M; 29 30 bool check(ll mid){ 31 ll cnt = 0; 32 ll pre = 0; 33 for(ll i = 1 ; i <= N ; i ++){ 34 if(D[i]-D[pre]>=mid){ 35 pre = i; 36 }else{ 37 cnt++; 38 } 39 if(cnt > M) return false; 40 } 41 return true; 42 } 43 44 int main(){ 45 while(scanf("%d%d%d",&L,&N,&M) != EOF){ 46 D[0] = 0; 47 for(int i = 1 ; i <= N ; i ++) scanf("%lld",&D[i]); 48 D[++N] = L; 49 sort(D,D+N); 50 ll l = 0 , r = 1000000000; 51 while(l <= r){ 52 ll mid = l + (r-l)/2; 53 // 是否可能使得所有石头之间的距离不小于 mid 54 if(check(mid)){ 55 l = mid+1; 56 }else{ 57 r = mid-1; 58 } 59 } 60 printf("%lld\n",l-1); 61 } 62 63 return 0; 64 }
时间: 2024-11-08 22:28:19