Codeforces Round #477 Div.2
后一个半小时不知道在干嘛orz , rank硬生生掉了几百。
A. Mind the Gap
照着题目说的做就行了
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<stack>
using namespace std;
typedef long long ll;
const int N = 105 , Mod = 1e9 + 7;
int n , s;
int h[N] , m[N];
int main(){
scanf("%d%d",&n,&s);
bool flag = true;
for(int i = 1 ; i <= n ; i++){
scanf("%d%d",&h[i],&m[i]);
if(i != 1 && flag){
if(((h[i] * 60 + m[i]) - (h[i - 1] * 60 + m[i - 1])) >= (2 * s + 2)){
int ansmin = m[i - 1] + s + 1 , anshour = h[i - 1];
if(ansmin >= 60) anshour += ansmin / 60 , ansmin %= 60;
flag = false;
printf("%d %d\n", anshour , ansmin);
}
}
if(i == 1){
if(h[i] * 60 + m[i] >= s + 1){
printf("0 0\n");
flag = false;
}
}
}
if(flag){
int ansmin = m[n] + s + 1 , anshour = h[n];
if(ansmin >= 60) anshour += ansmin / 60 , ansmin %= 60;
printf("%d %d\n",anshour,ansmin);
}
return 0;
}
B. Watering System
排序后贪心。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<stack>
using namespace std;
typedef long long ll;
const int N = 100005 , Mod = 1e9 + 7;
const double eps = 1e-4;
ll n , a , b , s[N] , sum , cnt;
bool comp(ll x , ll y){
return x > y;
}
int main(){
scanf("%I64d%I64d%I64d",&n,&a,&b);
for(int i = 1 ; i <= n ; i++){
scanf("%I64d",&s[i]);
sum += s[i];
}
sort(s + 2 , s + 2 + n , comp);
bool flag = true;
if(a * s[1] >= b * sum){
printf("0\n");
return 0;
}
int ans = 0;
for(int i = 2 ; i <= n ; i++){
ans++; cnt += s[i];
if((sum - cnt) * b <= s[1] * a){
printf("%d\n",ans);
return 0;
}
}
return 0;
}
C. Stairs and Elevators
对每个询问分类讨论 , 总共有四种情况:
(1) 向左走找到一个楼梯上楼。
(2) 向右走找到一个楼梯上楼。
(3) 向左走找到一个电梯上楼。
(4) 向右走找到一个电梯上楼。
用二分找电梯/楼梯的位置 , 每种方法求最小值 ,复杂度 $ O(qlogn) $
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<stack>
using namespace std;
typedef long long ll;
const int N = 100005 , Mod = 1e9 + 7;
int n , m , l , e , v;
int sta[N] , ele[N];
int main(){
scanf("%d%d%d%d%d",&n,&m,&l,&e,&v);
for(int i = 1 ; i <= l ; i++) scanf("%d",&sta[i]);
for(int i = 1 ; i <= e ; i++) scanf("%d",&ele[i]);
sta[l + 1] = ele[e + 1] = m + 1;
int q , x1 , x2 , y1 , y2; scanf("%d",&q);
for(int i = 1 ; i <= q ; i++){
int ans = Mod , tag;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
if(x1 == x2)
printf("%d\n",abs(y1 - y2));
else{
tag = lower_bound(sta , sta + l + 1 , y1) - sta;
if(tag != l + 1) ans = min(ans , abs(y1 - sta[tag]) + abs(y2 - sta[tag]) + abs(x1 - x2));
if(tag != 1) ans = min(ans , abs(y1 - sta[tag - 1]) + abs(y2 - sta[tag - 1]) + abs(x1 - x2));
tag = lower_bound(ele , ele + e + 1 , y1) - ele;
if(tag != e + 1) ans = min(ans , abs(y1 - ele[tag]) + abs(y2 - ele[tag]) + (int)ceil((double)abs(x1 - x2) / v));
if(tag != 1) ans = min(ans , abs(y1 - ele[tag - 1]) + abs(y2 - ele[tag - 1]) + (int)ceil((double)abs(x1 - x2) / v));
printf("%d\n",ans);
}
}
return 0;
}
D. Resource Distribution
对每个服务器的资源按递减排序 , 然后令 $ p_{i , 1} = \lceil \frac{x_{1}}{c_{i}} \rceil , p_{i , 2} = \lceil \frac{x_{2}}{c_{i}} \rceil $ 表示选了编号为 $ i $ 的服务器放在 $ x1 $ 或 $ x2 $ 后 , $ x1 $ 或 $ x2 $ 至少需要放多少个服务器。
先考虑满足 $ x1 $ 再考虑满足 $ x2 $ , 相反同理。
在 $ p_{*,1} $ 枚举 $ pos $ , 找到满足 $ pos >= p_{pos , 1} $ , 然后再检验 $ x2 $ 是否可行 , 即在区间 $ [pos + 1 , n] $ 能否找到满足 $ pos' - p_{pos' , 2} >= p_{pos , 1} $ 的 $ pos' $。
检验可以 $ O(n) $ 预处理 , 方法看代码。 复杂度 $ O(nlogn + n) $
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<stack>
using namespace std;
typedef long long ll;
const int N = 300005 , Mod = 1e9 + 7 , INF = 0x3f3f3f3f;
struct data{
int pos , c;
}S[N];
bool comp(data x , data y){
return x.c > y.c;
}
int cnt , x1 , x2 , n;
int s[N] , num[N] , c1[N] , c2[N] , f1[N][2] , f2[N][2];
vector<int> ans1 , ans2;
bool flag;
bool check(int x , int c[] , int cnt){
int l = x + 1 , r = n;
while(l <= r){
int mid = (l + r) >> 1;
if(c2[mid] > cnt) r = mid - 1;
else if(c2[mid] <= cnt) return true;
}
}
void solve(){
int temp;
f1[n + 1][0] = f2[n + 1][0] = -INF;
for(int i = n ; i >= 1 ; i--){
if(i - c1[i] > f1[i + 1][0]){
f1[i][0] = i - c1[i];
f1[i][1] = i;
}
else f1[i][0] = f1[i + 1][0] , f1[i][1] = f1[i + 1][1];
if(i - c2[i] > f2[i + 1][0]){
f2[i][0] = i - c2[i];
f2[i][1] = i;
}
else f2[i][0] = f2[i + 1][0] , f2[i][1] = f2[i + 1][1];
}
for(int i = 1 ; i < n ; i++)
if(i >= c1[i] && (f2[i + 1][0] >= c1[i])){
flag = true;
for(int j = 0 ; j < c1[i] ; j++) ans1.push_back(num[i - j]);
for(int j = 1 ; j <= i - c1[i] ; j++) ans2.push_back(num[j]);
for(int j = i + 1 ; j <= f2[i + 1][1] ; j++) ans2.push_back(num[j]);
break;
}
if(flag) return;
for(int i = 1 ; i < n ; i++)
if(i >= c2[i] && (f1[i + 1][0] >= c2[i])){
flag = true;
for(int j = 0 ; j < c2[i] ; j++) ans2.push_back(num[i - j]);
for(int j = 1 ; j <= i - c2[i] ; j++) ans1.push_back(num[j]);
for(int j = i + 1 ; j <= f1[i + 1][1] ; j++) ans1.push_back(num[j]);
break;
}
}
int main(){
scanf("%d%d%d",&n,&x1,&x2);
int l = 1 , r = n - 1;
for(int i = 1 ; i <= n ; i++){
S[i].pos = i;
scanf("%d",&S[i].c);
}
sort(S + 1 , S + 1 + n , comp);
for(int i = 1 ; i <= n ; i++) s[i] = S[i].c , num[i] = S[i].pos;
for(int i = n ; i >= 1 ; i--){
c1[i] = ceil((double) x1 / s[i]);
c2[i] = ceil((double) x2 / s[i]);
}
solve();
if(flag){
puts("Yes");
printf("%d %d\n" , ans1.size() , ans2.size());
for(int i = 0 ; i < ans1.size() ; i++) printf("%d " , ans1[i]);
cout << endl;
for(int i = 0 ; i < ans2.size() ; i++) printf("%d " , ans2[i]);
cout << endl;
}
else puts("No");
return 0;
}
E 题 和 F 题感觉不是很可写 , 弃了qwq