Educational Codeforces Round 121 (Rated for Div. 2)

A

直接sort即可。

B

经过分析可得,相邻的和一定会使整个数变小,那么贪心的去找,是否存在两个数之和>=10,来保证其位数不会减小,并且在最后的两个数之和>=10的位置去修改,

如果整个数不存在相邻的两数之和>=10,那么操作之后必将导致数位-1,那么此时优先于加前两个,会使数的最高位尽量变大。

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define pb push_back
void solve(){
	string s;
	cin>>s;
	int fg=0;
	int len=s.size();
	int pos=0;
	for(int i=len-1;i>0;i--){
		int a=s[i-1]-'0'+s[i]-'0';
		if(a>=10){
			fg=1;pos=i;
			break;
		}
	}if(!fg){
		cout<<s[0]-'0'+s[1]-'0';
		for(int i=2;i<len;i++)cout<<s[i];
	}else{
		for(int i=0;i<pos-1;i++)cout<<s[i];
		cout<<s[pos-1]-'0'+s[pos]-'0';
		for(int i=pos+1;i<len;i++)cout<<s[i];
	}cout<<"\n";
} 
int main(){
	int t=1;
	cin>>t;
	while(t--){
		solve();
	}
}

C

分析可得,每个怪物覆盖了一段区间,我们只需要求出每一个不相重合的区间的值,然后记录ans即可。

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define pb push_back
const int N=105;
struct node{
	ll r,w;
	ll l;
}a[N];
bool cmp(node x,node y){
	if(x.l==y.l)return x.r>y.r;
	return x.l<y.l;
}
void solve(){
	int n;
	cin>>n;
	for(int i=0;i<n;i++)cin>>a[i].r;
	for(int i=0;i<n;i++)cin>>a[i].w,a[i].l=a[i].r-a[i].w+1;
	sort(a,a+n,cmp);
	ll ans=0;
	ll l=a[0].l,r=a[0].r;
	for(int i=1;i<n;i++){
		if(a[i].l<=r){
			r=max(r,a[i].r);
		}else{
			ll cnt=r-l+1;
			ans+=cnt*(cnt+1)/2;
			l=a[i].l;
			r=a[i].r;
		}
	}ll cnt=r-l+1;
	ans+=cnt*(cnt+1)/2;
	cout<<ans<<"\n";
} 
int main(){
	int t=1;
	cin>>t;
	while(t--){
		solve();
	}
}

D:

将所给定的数分成三部分,使三部分的数的个数的接近于2的幂次,求出最小的添加的数的数量,

因为是将数分为三部分,那么只需要枚举前两部分的2的幂次,然后O(n)进行判断,最后取min即可

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define pb push_back
const int N=2e5+5;
int cnt[N];
int n;
set<int> s;
int check(int x1,int x2){
	int ned=0;
	int pos=1;
	int sum=0;
	for(;pos<=n;pos++){
		if(sum+cnt[pos]>x1)break;
		sum+=cnt[pos];
	}ned+=x1-sum;sum=0;
	for(;pos<=n;pos++){
		if(sum+cnt[pos]>x2)break;
		sum+=cnt[pos];
	}ned+=x2-sum;
	sum=0;
	for(;pos<=n;pos++){
		sum+=cnt[pos];
	}
	ned+=*s.lower_bound(sum)-sum;
	return ned;
}
void solve(){
	cin>>n;
	for(int i=1;i<=n;i++)cnt[i]=0;
	for(int i=1;i<=n;i++){
		int a;
		cin>>a;cnt[a]++;
	}int ans=1e9;
	for(int i=0;i<=20;i++){
		for(int j=0;j<=20;j++){
			ans=min(ans,check(1<<i,1<<j));
		}
	}cout<<ans<<"\n";
}
int main(){
	int t=1;
	for(int i=0;i<=20;i++){
		s.insert(1<<i);
	}
	cin>>t;
	while(t--){
		solve();
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值