CF830A/831D Office Keys

思路:

问题的关键在于对钥匙按照位置排序之后,最终选择的n个钥匙一定是其中的一个连续的区间。

实现:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <algorithm>
 5 using namespace std;
 6 typedef long long ll;
 7 const ll INF = 0x3f3f3f3f3f3f3f3f;
 8 ll man[1005], key[2005];
 9 ll cal(ll m, ll k, ll p)
10 {
11     if ((k >= m && k <= p) || (k <= m && k >= p)) return abs(m - p);
12     return abs(m - k) + abs(k - p);
13 }
14 int main()
15 {
16     ll n, k, p, ans = INF;
17     cin >> n >> k >> p;
18     for (int i = 0; i < n; i++) cin >> man[i];
19     for (int i = 0; i < k; i++) cin >> key[i];
20     sort(man, man + n); sort(key, key + k);
21     for (int i = 0; i <= k - n; i++)
22     {
23         ll maxn = 0;
24         for (int j = 0; j < n; j++)
25         {
26             maxn = max(maxn, cal(man[j], key[j + i], p));
27         }
28         ans = min(ans, maxn);
29     }
30     cout << ans << endl;
31     return 0;
32 }
时间: 2024-08-10 19:19:17

CF830A/831D Office Keys的相关文章

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿

【CodeForces】 830A Office Keys

传送门 codeforces luogu 题目描述 There are n people and k keys on a straight line. Every person wants to get to the office which is located on the line as well. To do that, he needs to reach some point with a key, take the key and then go to the office. Onc

Codeforces VK Cup Finals #424 Div.1 A. Office Keys(DP)

显然是不可能交叉取钥匙的,于是把钥匙和人都按坐标排序就可以DP了 钥匙可以不被取,于是f[i][j]表示前i个钥匙被j个人拿的时间 f[i][j]=min(f[i-1][j],max(f[i-1][j-1],abs(b[i]-a[j])+abs(P-b[i])); #include<bits/stdc++.h> #define ll long long using namespace std; const int maxn=1010,inf=2e9; int n,k,p; int a[maxn

【推导】Codeforces Round #424 (Div. 1, rated, based on VK Cup Finals) A. Office Keys

选择的钥匙一定是连续的,人和钥匙一定从左到右连续对应. 就枚举钥匙区间即可. #include<cstdio> #include<algorithm> using namespace std; int Abs(int x){ return x<0 ? (-x) : x; } int n,K,p,a[1010],ans=2147483647,b[2010]; int main(){ scanf("%d%d%d",&n,&K,&p);

Codeforces 830A. Office Keys (背包dp+贪心) / (二分+贪心)

题目链接: http://codeforces.com/problemset/problem/830/A 题意: n个人,k个钥匙(n<=k),p表示这些人要到达的位置 给出n个人的位置以及钥匙的位置,问花时间最多的那个人用时最少是多少?? 思路: 二分+贪心: 二分最少时间,需要对a,b位置数组排序,我们check函数只需要从左到右一个一个找过去,因为如果选后边的点,可能会使结果更差,假如当前这个人选后面的点,那可能会选中后面的人可以选的唯一的钥匙,不会使解更优. check(40)的时候答案

A. Office Keys (from Codeforces Round #424 (Div. 1, rated, based on VK Cup Finals) )

1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <algorithm> 5 using namespace std; 6 7 int a[150000]; 8 int b[150000]; 9 int dp[1005][1005]; 10 //dp[i][j] 前i个人从前j个药匙中到达终点的最小时间 11 12 int main() 13 { 14 in

Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals)

D题fst了,生无可恋.第二场rated的CF,打得精神恍惚 A. Unimodal Array 题意:判断数列是否是单峰的. 像题意那样分为三个阶段随便判一判就好了 #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> using namespace std; int n,x[105],part=1; bool f=1; int main() { scanf(&quo

cf 424

Office Keys 首先显然有随人位置的递增,钥匙的位置也要递增,这样考虑两张做法: 1.$f(i,j)$ 表示前i个人,钥匙到第j个最少用的最大时间,然后$O(nK)$ dp 2.二分时间,对于每一个人选择当前能选择的最左面的钥匙 $O((n+K) logn)$ #include <bits/stdc++.h> #define LL long long const int N = 2010; using namespace std; int n,m,pre[N],a[N],b[N]; i

Codeforces Round #424 (Div. 2) D 思维 E set应用,树状数组

Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) D. Office Keys 题意:一条直线上,有个办公室坐标 p,有 n个人在a[i],有 k把钥匙在b[i],每个人必须拿到一把钥匙,然后到办公室.问怎么安排花的时间最短. tags:还是不懂套路啊..其实多画两下图就能够感觉出来,2333 关键是要看出来,n个人拿的 n把钥匙应该是连续的. 然后,就是瞎暴力.. #include<bits/stdc++.h> usi