Codeforces Global Round 3

A. Another One Bites The Dust

题意:有三种字符的若干数目,求使得这些字符拼接起来前后字符不一样的最长字符长度。

思路:首先a,b,c可以拼接成长度为4的字符,然后再接c可以拼接长度为2的字符,最后再判断a和b还有没有剩余。

#include<bits/stdc++.h>
using namespace std;
int main(){
	int a,b,c;
	long long ans=0;
	scanf("%d%d%d",&a,&b,&c);
	int t=min(a,min(b,c));
	ans=(long long)4*t;
	a-=t;
	b-=t;
	c-=t;
	ans+=(long long)2*c;
	t=min(a,b);
	ans+=(long long)2*t;
	a-=t;
	b-=t;
	if(a!=0)
		ans++;
	if(b!=0)
		ans++;
	printf("%lld\n",ans);
}

B. Born This Way

题意:乘客可以在a序列的任意时刻上车,花费ta时间到达b车站,再花费tb时间到达c,你可以取消最多k个时刻,问他最迟什么时候到c站。

思路:暴力加二分。

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n,m,ta,tb,k;
	scanf("%d%d%d%d%d",&n,&m,&ta,&tb,&k);
	for(int i=0;i<n;i++)
		scanf("%lld",&a[i]);
	for(int i=0;i<m;i++)
		scanf("%lld",&b[i]);
	if(k>=n||k>=m)
		puts("-1"); 
	else{
		long long ans=-1;
		long long t;
		for(int i=0;i<=k;i++){
			t=(long long)(a[i]+ta);
			int p1=lower_bound(b,b+m,t)-b;
			if((long long)(p1+k-i)<m)
				ans=max(ans,b[(long long)p1+k-i]+tb);
			else {
					puts("-1");
					return 0;
				}
			}
		printf("%lld\n",ans);
	}
	return 0;
}

C. Crazy Diamond

题意:给定数组,如果两个数下标满足2*|i-j|>=n,那么这两个数能交换,问最终使得数组有序操作。

思路:用一个数组保存每个数的下标,从1到n遍历一遍,如果符合要求就换,否则利用1和n来换。

#include<bits/stdc++.h>
using namespace std;
int a[300005],b[300005];
typedef pair<int,int>p;
vector<p>v;
void change(int x,int y){
	b[a[x]]=y;
	b[a[y]]=x;
	v.push_back(p(x,y));
	swap(a[x],a[y]);
}
int main(){
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]),b[a[i]]=i;
	int ans=0;
	for(int i=1;i<n;i++){
		if(b[i]==i)
			continue;
		if(2*(b[i]-i)>=n){
			ans++;
			change(i,b[i]);
		}
		else{
			if(2*(b[i]-1)>=n){
				if(2*(i-1)>=n){
					ans+=3;
					int x=b[i];
					change(1,b[i]);
					change(1,i);
					change(1,x);
				}
				else{
					ans+=4;
					int x=b[i];
					change(1,b[i]);
					change(1,n);
					change(i,n);
					change(1,x);
				}
			}
			else{
				ans+=2;
				change(b[i],n);
				change(i,n);
			}
		}
	}
	printf("%d\n",ans);
	for(int i=0;i<v.size();i++)
		printf("%d %d\n",v[i].first,v[i].second);
}

D. Dirty Deeds Done Dirt Cheap

题意:给定n个a和b的元组,问怎样最多选择他们的顺序符合要求。

思路:两次排序就可以了。

#include<bits/stdc++.h>
using namespace std;
struct node{
	int c,id;
};
node a[300005],b[300005];
int cmp1(node a,node b){
	return a.c<b.c;
}
int cmp2(node a,node b){
	return a.c>b.c;
}
int main(){
	int n;
	scanf("%d",&n);
	int t1=0,t2=0,x,y;
	for(int i=1;i<=n;i++){
		scanf("%d%d",&x,&y);
		if(x<y)
			a[t1].c=y,a[t1++].id=i;
		else b[t2].c=x,b[t2++].id=i;
	}
	sort(a,a+t1,cmp2);
	sort(b,b+t2,cmp1);
	if(t1>t2){
		printf("%d\n",t1);
		for(int i=0;i<t1;i++)
			printf("%d ",a[i].id);
	}
	else {
		printf("%d\n",t2);
		for(int i=0;i<t2;i++)
			printf("%d ",b[i].id);
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值