CF Round #537 (Div. 2)

ACM题集:https://blog.csdn.net/weixin_39778570/article/details/83187443
题目链接:https://codeforces.com/contest/1111

A
元音之间可以互相转换,辅音之间可以互相转换,
若两个句子无法转换成同个句子输出No
否则输出Yes 
#include<bits/stdc++.h>
#define ll long long
#define fo(i,j,n) for(register int i=j; i<=n; ++i)
using namespace std;
int a[1005],b[1005];
string s,t;
int main(){
	cin>>s>>t;
	if(s.length()!=t.length()){
		cout<<"No";
	}else{
		for(int i=0; i<s.length(); i++){
			if(s[i]=='a'||s[i]=='e'||s[i]=='i'||s[i]=='o'||s[i]=='o'||s[i]=='u'){
				a[i] = 1;
			}else a[i]=2;
			if(t[i]=='a'||t[i]=='e'||t[i]=='i'||t[i]=='o'||t[i]=='o'||t[i]=='u'){
				b[i] = 1;
			}else b[i]=2;
			if(a[i]!=b[i]){
				cout<<"No";
				return 0;
			}
		}
		cout<<"Yes";
	}
	return 0;
}
B
现在有一个数列
你可以进行m次操作
操作1:删除一个数
操作2:对一个数加上1,一个数最大加k
现在问剩下的数列的平均值最大为多少
-------------------------------------
对数列排序好,然后我们尽可能删除掉小的数,并且加上所有能加的数
假设删了i个数,sum表示剩下的数的和 
那么 avg = (sum + min(m-i,(n-i)*k) )/(n-i) 取其中最小的那一个 
#include<bits/stdc++.h>
#define ll long long
#define fo(i,j,n) for(register int i=j; i<=n; ++i)
using namespace std;
ll n,k,m; //改int过不了,后面有用到 
ll a[100100],sum;
signed main(){
	cin>>n>>k>>m;
	for(int i=1;i<=n;i++) scanf("%lld",a+i),sum+=a[i];
	sort(a+1,a+1+n);
	double avg = 1.0*(sum+min(m,n*k))/n; // 不删 
	for(int i=1; i<=min(n-1,m); i++){ // 删除i个小的 
		sum -= a[i];
		avg = max(avg,1.0*(sum+min(m-i,(n-i)*k))/(n-i)); // 加上(n-i)*k全加满或全加完m-i   
	}
	printf("%.15f",avg);
}
C
有个基地,长度为1-2^n,基地上有的有复仇者守着,有的没有
对一个基地你可以直接破坏掉他,也可以把他分成等长的两部分来破坏(长度大于等于2) 
直接破坏:如果 L到R 号中的基地没有复仇者 破坏的代价为A
		 否则 代价 = B*na*len  na表示有复仇者的基地的数量,len表是基地的长度
#include<bits/stdc++.h>
#define ll long long
#define fo(i,j,n) for(register int i=j; i<=n; ++i)
using namespace std;

ll n,k,A,B;
ll a[100005];
ll rec(ll l, ll r){
	// 基地l到r种有复仇者的数量
	ll na = upper_bound(a,a+k,r)-lower_bound(a,a+k,l);
	ll destroyNow;
	if(na==0){
		destroyNow = A;
	}else{
		destroyNow = B * na * (r-l+1);
	}
	if(l==r || na==0)return destroyNow; // 无法分,或者找不到了(直接解决掉) 
	else{
		ll mid = (l+r)>>1;
		return min(destroyNow, rec(l,mid)+rec(mid+1,r));
	} 
}
int main(){
	cin>>n>>k>>A>>B;
	fo(i,0,k-1)scanf("%lld",&a[i]);
	sort(a,a+k);
	cout<<rec(1ll,1ll<<n);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值