题意:在一个数轴上面有k把钥匙n个人,在p位置有一个办公室,每个人需要拿一把钥匙才能进办公室,每个人走一步的时间是1,求最少多少时间每个人都能到办公室
思路:二分时间,每次check判断是否所有人都能拿到钥匙进入办公室,check的时候从从左到右判断每个人,每次在能取到钥匙的前提下取最左边的钥匙,这样才那保证对后面的人是最优的,当前不需要保证最优,因为时间已经给定,只需要保证在t时间内拿到钥匙进入办公室即可,但是如果不保证对后面的人是最优的话,后面的人得出的结论就不是最优的
AC代码:
#include "iostream" #include "string.h" #include "stack" #include "queue" #include "string" #include "vector" #include "set" #include "map" #include "algorithm" #include "stdio.h" #include "math.h" #define ll long long #define bug(x) cout<<x<<" "<<"UUUUU"<<endl; #define mem(a) memset(a,0,sizeof(a)) #define mp(x,y) make_pair(x,y) using namespace std; const long long INF = 1e18+1LL; const int inf = 1e9+1e8; const int N=1e5+100; int n,k,p,a[2005],b[2005]; bool check(ll x){ int po=1; for(int i=1; i<=n; ++i){ int tx=x-abs(a[i]-p)>>1; if(tx<0) return 0; int l,r; if(a[i]<=p){ l=a[i]-tx; r=p+tx; } else{ l=p-tx; r=a[i]+tx; } int f=1; for(int j=po; j<=k; ++j){ if(b[j]>=l && b[j]<=r){ po=j+1; f=0; break; } } if(f) return 0; } return 1; } int main(){ ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); cin>>n>>k>>p; for(int i=1; i<=n; ++i){ cin>>a[i]; } for(int i=1; i<=k; ++i){ cin>>b[i]; } sort(a+1,a+1+n); sort(b+1,b+1+k); check(7); ll l=0,r=2e9+10,ans=0; while(l<=r){ ll mid=l+r>>1; if(check(mid)) ans=mid,r=mid-1; else l=mid+1; } cout<<ans; return 0; }