1. 程式人生 > >二分,求直線上覆蓋所有點的最短時間

二分,求直線上覆蓋所有點的最短時間

org for 比較 bool begin cef complex ref hid

http://codeforces.com/group/aUVPeyEnI2/contest/230300/problem/E

參考自:https://blog.csdn.net/u013508213/article/details/49594691

題意:

給n個內存讀取指針頭,m個需要訪問的內存地址(1??n,?m??1051?≤?n,?m?≤?105) ,每一秒鐘,指針頭可以向左移動或者向右移動一個單位,問最少需要多少時間,能把這些內存地址訪問完。

solution:

二分固定時間t,ok函數的寫法是:
當當前的指針頭小於當前需要訪問的內存節點時,指針頭不斷往前移動就好了;
當當前的指針頭大於當前需要訪問的內存節點時,需要做個比較:
首先是當前指針頭先往左移動到需要訪問的內存節點,再移動回來往前移動,此時還可以往前移動的時間是t?2?(head[i]?track[cnt])t?2?(head[i]?track[cnt]);
然後是當前指針頭先往右移動足夠遠,然後再回來訪問需要訪問的內存節點,此時可以往前移動的時間是(t?(head[i]?track[cnt]))/2(t?(head[i]?track[cnt]))/2。
取二者大的往前移動即可。
若計數cnt>=m,說明時間充裕。

技術分享圖片
 1 /*************************************************************************
 2     > File Name:  
 3     > Author: QWX
 4     > Mail: 
 5     > Created Time: 2018/10/11 18:11:28
 6  ************************************************************************/
 7 
 8 
 9 //{{{ #include
10 #include<iostream>
11
#include<cstdio> 12 #include<algorithm> 13 #include<vector> 14 #include<cmath> 15 #include<queue> 16 #include<map> 17 #include<set> 18 #include<string> 19 #include<cstring> 20 #include<complex> 21 #include<bits/stdc++.h> 22 #define mp make_pair 23
#define pb push_back 24 #define first fi 25 #define second se 26 #define pw(x) (1ll << (x)) 27 #define sz(x) ((int)(x).size()) 28 #define all(x) (x).begin(),(x).end() 29 #define rep(i,l,r) for(int i=(l);i<(r);i++) 30 #define per(i,r,l) for(int i=(r);i>=(l);i--) 31 #define FOR(i,l,r) for(int i=(l);i<=(r);i++) 32 #define cl(a,b) memset(a,b,sizeof(a)) 33 #define fastio ios::sync_with_stdio(false);cin.tie(0); 34 #define lson l , mid , ls 35 #define rson mid + 1 , r , rs 36 #define INF 0x3f3f3f3f 37 #define LINF 0x3f3f3f3f3f3f3f3f 38 #define ll long long 39 #define ull unsigned long long 40 #define dd(x) cout << #x << " = " << (x) << "," 41 #define de(x) cout << #x << " = " << (x) << "\n" 42 #define endl "\n" 43 using namespace std; 44 //}}} 45 46 const int N=1e5+7; 47 ll a[N],b[N]; 48 int n,m; 49 bool check(ll t) 50 { 51 int cnt=0; 52 rep(i,0,n){ 53 if(t<abs(a[i]-b[cnt]))continue; 54 ll d=a[i]; 55 if(a[i]<b[cnt])d+=t; 56 else d+=max((t-(a[i]-b[cnt]))/2,t-2*(a[i]-b[cnt])); 57 while(cnt<m&&b[cnt]<=d)cnt++; 58 } 59 return cnt>=m; 60 } 61 62 int main() 63 { 64 fastio; 65 cin>>n>>m; 66 rep(i,0,n)cin>>a[i]; 67 rep(i,0,m)cin>>b[i]; 68 ll l=0,r=1e11,ans=0; 69 while(l<=r){ 70 ll mid=(l+r)>>1; 71 if(check(mid))r=mid-1,ans=mid; 72 else l=mid+1; 73 } 74 cout<<ans<<endl; 75 return 0; 76 }
View Code

二分,求直線上覆蓋所有點的最短時間