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

posted @ 2018-05-01 00:05  FranceDisco  阅读(119)  评论(0编辑  收藏  举报