Educational Codeforces Round 172 (Rated for Div. 2)A~C题解

这场发挥的也是有点呆了,d题都过去1000多号人了,我还没过去,不知道为什么一直错在第二个点,可能是我想的太少了

话不多说,先看题吧

A. Greedy Monocarp

题意:给你n个箱子,每个箱子有若干金币,但是这些箱子的金币总和至少达到k,然后M那个人偷金币,他会从最多金币的箱子开始偷,然后至少偷满k个金币 

思路:一开始看错题了,没看到那个从最多的金币箱子开始偷,导致我一开始一直没想到思路,因为深搜+记忆化搜索我感觉也会超时,后面看到了从最多金币箱子开始偷就直接秒了,从大到小排序一遍,找到小于k的时候最接近k的一个数目,然后找到最小差值输出即可

#include <bits/stdc++.h>  
using namespace std;  
#define int long long  

int t;  
int n, k;  
int a[200005];  
int min_diff;  
bool cmp(int a,int b)
{
	return a>b;
}

void solve() 
{  
    cin >> n >> k;  
    int sum = 0;  
    
    for (int i = 0; i < n; i++) 
	{  
        cin >> a[i];  
        sum += a[i];  
    }  
    sort(a,a+n,cmp);
    if (sum <= k) 
	{  
        cout << k - sum << "\n";  
        return;  
    } 
	else 
	{
		int cnt=0;
		int minn=k;
		for(int i=0;i<n;i++)
		{
			cnt+=a[i];
			if(cnt>k)
			{
				break;
			}
			minn=min(minn,k-cnt);
		}
		cout<<minn<<"\n";
	 } 
}  

signed main() {  
    ios::sync_with_stdio(0);  
    cin.tie(0);  
    cout.tie(0);  
    cin >> t;  
    while (t--) {  
        solve();  
    }  
    return 0;  
}

B. Game with Colored Marbles

题意:就是说有n个弹珠,每个弹珠都有自己的颜色,拿到一个颜色的弹珠加一分,但是后续继续拿这个颜色就不加分了,拿到同一个颜色所有的弹珠可以额外加一分 

思路:先把颜色只有一个球的弹珠拿了,这样可以一次性加两分,然后剩下的颜色有多个球的,每次只拿其中一颗即可

#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n,k;
int a[200005];
void solve()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	sort(a+1,a+1+n);
	
	int cnt=0;
	for(int i=1;i<=n;i++)
	{
		if(a[i-1]!=a[i]&&a[i+1]!=a[i])
		{
			cnt++;
		}
	}
	int len=unique(a+1,a+1+n)-a-1;
	cout<<(cnt+1)/2*2+(len-cnt)*1<<"\n";
	for(int i=1;i<=n;i++)
	{
		a[i]=0;
	}
}

signed main()
{
    ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>t;
	while(t--)
	solve();
	return 0;
}

C. Competitive Fishing

题意:就是说给你n条鱼,用二进制字符串去表示(1为鲍勃钓的,0为爱丽丝钓的),然后将这个二进制序列进行分组,第i组的每条鱼的分值是i-1,然后问你鲍勃是否能够领先爱丽丝至少k分

思路:我们通过观察可以发现,当我们在一个位置之前划上一个分组的时候,其后缀相当于所有元素都+1分,所以我们要统计后缀合,然后将后缀和去进行排序,然后累加,去判断是否能达到k,如果小于k,那么就要输出-1,否则就去统计刚才划了多少的线,然后输出n-线的数量+1就是组数,但是我们等下排序的时候不能统计第一位,因为第一位永远是0

#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n,k;
int a[200005];
string s;
void solve()
{
	cin>>n>>k;
	cin>>s;
	s=' '+s;
    for(int i=1;i<=n;i++)
    {
        if(s[i]=='0')
		{
			a[i]=-1;
		}
        else 
		{
			a[i]=1;
		}
    }
    for(int i=n-1;i>=1;i--)
	{
		a[i]+=a[i+1];
	}
    int ans=0;
	int z=n;
    sort(a+2,a+1+n);
    while(z>1&&ans<k)
	{
		ans+=a[z];
		z--;
	}
    if(ans<k)
	{
		cout<<-1<<"\n";
	}
    else 
	{
		cout<<n-z+1<<"\n";
	}
}
signed main()
{
    ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>t;
	while(t--)
	solve();
	return 0;
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值