您的位置:首页 > 其它

codeforces 343C Read Time 【二分】

2015-08-27 14:02 337 查看
C. Read Time

Mad scientistMike does not use slow hard disks. His modification of a hard drive has notone, but n different heads that can read data
in parallel.
When viewed fromthe side, Mike's hard drive is an endless array of tracks. The tracks of thearray are numbered from left to right with integers, starting with 1. In theinitial state the i-th
reading head is above the track number hi. For each ofthe reading heads, the hard drive's firmware can move the head exactly onetrack
to the right or to the left, or leave it on the current track. During theoperation each head's movement does not affect the movement of the other heads:the heads can change their relative order; there can be multiple reading headsabove any of the tracks. A
track is considered read if atleast one head has visited this track. In particular, all of the tracksnumbered h1, h2, ..., hn have
beenread at the beginning of the operation.
Mike needs toread the data on m distinct tracks with numbers p1, p2, ..., pm.
Determine theminimum time the hard drive firmware needs to move the heads and read all thegiven tracks. Note that an arbitrary number of other tracks can also be read.
Input
The first lineof the input contains two space-separated integers n, m (1 ≤ n, m ≤ 105)
— the numberof disk heads and the number of tracks to read, accordingly. The second linecontains n distinct integers hi inascending
order (1 ≤ hi ≤ 1010, hi < hi + 1)
— the initialpositions of the heads. The third line contains m distinctintegers pi in
ascending order (1 ≤ pi ≤ 1010, pi < pi + 1)
- the numbersof tracks to read.
Please, do notuse the %lld specifierto read or write 64-bit integers in С++. It is recommended to use the cin, cout streams
orthe%I64d specifier.
Output
Print a singlenumber — the minimum time required, in seconds, to read all the needed tracks.
Sample test(s)
input
3 4

2 5 6

1 3 6 8
output
2
input
3 3

1 2 3

1 2 3
output
0
input
1 2

165

142 200
output
81
Note
The first testcoincides with the figure. In this case the given tracks can be read in 2seconds in the following way:
1.   during the first second move the 1-st head to the leftand let it stay there;
2.   move the second head to the left twice;
3.   move the third head to the right twice (note that the6-th track has already been read at the beginning).
One cannot readthe tracks in 1 second as the 3-rd head is at distance 2 from the 8-th track.
 

题目链接: http://codeforces.com/problemset/problem/343/C
 

题意 :

       有一个长条形储存区,划分成一些小块;有N个读取头,M个待读取区域,读取区域中的内容耗时为0,移动一个区域耗时为1;读取头可同时移动和读取;问读取全部待读取区域的最少耗时是多少;

 

思路:

       二分,二分所需的时间;对二分的时间进行判定看是否符合要求,判定方法如下,从左至右,对每个磁头进行操作:

1.      如果该磁头左边没有待读取区域,则将该磁头向右移动至最远,记录最远位置,

2.      如果该磁头左边有待读取区域,若磁头与最远的区域距离大于时间,则返回fals;否则在 先向左到达左端最远未到达区域,再向右到最远
在能到达左边最远未到达区域的前提下先向右到最远再向左返回 两种操作中选出能到达更靠右的,记录最右的位置

3.      每操作一次磁头后,将每个位置在记录的最远位置左侧的待读取区域标记为已读取区域

4.      如果最后一个未读取区域可以读到,则返回true;

 

基本思路就是这样了

 

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
ll h[maxn],p[maxn];
bool vis[maxn];
int n,m;

bool isok(ll time){
int pos = 0;
ll hasVis = 0;
memset(vis,false,sizeof(vis));
for(int i = 0 ; i < n ; i++){
if(h[i] < p[pos])
hasVis = h[i] + time;
else{
if(time < h[i] -p[pos]){
return false;
}
hasVis = max (p[pos]+ time - (h[i]- p[pos]), h[i] + (time - (h[i]-p[pos]))/2);
}

for(int j = pos ; j <m ; j ++){
if(p[j] <= hasVis||vis[j])
vis[j] = true;
else{
pos = j;
break;
}
}

if(vis[m-1])
return true;
}
return false;
}
int main()
{
cin >>n>>m;
for(int i = 0 ; i< n ; i++)
scanf("%I64d",h+i);
for(int i = 0 ; i< m ; i++)
scanf("%I64d",p+i);

ll l = 0, r =2*max(p[m-1],h[m-1]);
while( l+1< r){
ll mid = (l+r) >>1;
if(isok(mid))
r = mid;
else
l = mid;
}
if(isok(l))
cout << l;
else
cout << r;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: