Educational Codeforces Round 176 (Rated for Div. 2)(A~D)

#补题

A. To Zero

题目:

思路:

考虑n的奇偶性就行了。

  • 奇数:先将n-k,n变成偶数,然后一直用偶数
  • 偶数:就直接一直用偶数就行了

代码:

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
ll inf=0x3f3f3f3f3f3f3f3f;
void solve(){
	ll k,n;cin>>n>>k;
	ll ans=0;
	if(n%2)n-=k,ans++;
	ans+=(n+k-2)/(k-1);
	cout<<ans<<endl;
	return;
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	ll _;cin>>_;
	while(_--)solve();
}

B. Array Recoloring

题目:

思路:

就选最大k+1个就行了,注意k==1时是特殊情况处理一下就行了。

代码:

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
ll inf=0x3f3f3f3f3f3f3f3f;
void solve(){
	ll n,k;cin>>n>>k;
	vector<ll> a(n+1);
	vector<ll> sm(n+1);
	for(ll i=1;i<=n;i++){
		cin>>a[i];
	}
	ll ans=0;
	if(k==1){
		for(ll i=1;i<n;i++){
			if(i==1){
				ans=max(ans,a[1]+a[n]);
			}else{
				ans=max(ans,a[i]+max(a[1],a[n]));
			}
		}
	}else{
		sort(a.begin()+1,a.end());
		for(ll i=max((ll)1,n-k);i<=n;i++)ans+=a[i];
	}
	cout<<ans<<endl;
	return;
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	ll _;cin>>_;
	while(_--)solve();
}

C. Two Colors

题目:

思路:

假如样例:

1

4 2

3 4

可能的结果是:

  • 1 2 2 2
  • 1 1 2 2
  • 1 1 1 2
  • 2 1 1 1
  • 2 2 1 1
  • 2 2 2 1

我们要选两种颜色填满n个位置,假如我们选了一个颜色图了cnt个位置,那么就还需要n-cnt个位置图上其他颜色,然后我们可以发现对于一个颜色比如这里的1,它可以图1~3,对应的需要1~3来补充,然后对于每一次补充我们又可以选择不同的颜色,所以我们只需要对除他自己以外的颜色统计一下贡献,然后求和就行了。

代码:

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
ll inf=0x3f3f3f3f3f3f3f3f;
void solve(){
	ll n,m;cin>>n>>m;
	vector<ll> a(m+1);
	for(ll i=1;i<=m;i++)cin>>a[i];
	vector<ll> sum(n+2);
	sum[1]=m;
	for(ll i=1;i<=m;i++){
		sum[a[i]+1]--;
	}
	for(ll i=1;i<=n;i++){
		sum[i]+=sum[i-1];
	}
	for(ll i=1;i<=n;i++){
		sum[i]+=sum[i-1];
	}
	ll ans=0;
	for(ll i=1;i<=m;i++){
		ll l=max(n-a[i],(ll)1);
		ll r=n-1;
		ll t=0;
		ll tr=a[i];
		if(tr==n)tr--;
		if(tr>=l){
			t=min(tr,r)-l+1;
		}
		ans+=sum[r]-sum[l-1]-t;
	}
	cout<<ans<<endl;
	return;
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	ll _;cin>>_;
	while(_--)solve();
}

D. Equalization

题目:

思路:

本质就是将一个数右移k位,所以我们只需求x>>i==y>>j时的最小方案数就行了,然后提前处理一个01背包就行了。(dp[i][j]代表x>>i,y>>j的最小代价。)

代码:

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
ll inf=0x3f3f3f3f3f3f3f3f;
ll ll1=1;
ll dp[61][61];
void solve(){
	ll x,y;cin>>x>>y;
	ll ans=inf;
	for(ll i=0;i<=60;i++){
		for(ll j=0;j<=60;j++){
			ll tx=x>>i;
			ll ty=y>>j;
			if(tx==ty){
				ans=min(ans,dp[i][j]);
			}
		}
	}
	cout<<ans<<endl;
	return;
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	memset(dp,0x3f,sizeof dp);dp[0][0]=0;
	for(ll k=1;k<=60;k++){
		for(ll i=60;i>=0;i--){
			for(ll j=60;j>=0;j--){
				if(i>=k)dp[i][j]=min(dp[i][j],dp[i-k][j]+(ll1<<k));
				if(j>=k)dp[i][j]=min(dp[i][j],dp[i][j-k]+(ll1<<k));
			}
		}
	}
	ll _;cin>>_;
	while(_--)solve();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值