Educational Codeforces Round 108 (Rated for Div. 2)

Educational Codeforces Round 108 (Rated for Div. 2)

A - Red and Blue Beans

题意:一共有n颗红豆与m颗蓝豆与最大误差x 假设你有无限个口袋每个口袋里面装的红豆与蓝豆最大值不得大于x并且装进口袋的蓝豆与红豆每种至少有一个 问你是否可行

思路:既然他的最大误差是x那么我们先找到红豆与蓝豆数量少的那个记为j 那么数量多的那种豆数量最大可以是j*(x+1) 如果数量比这个还多那么就是不可行的还有就是注意特判 两种豆数量相等的情况 1 x无论是什么数值都是可行的 2 当x==0时如果两种豆的数量不一样那么就是不可行的

代码如下:

#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
ll a,b,c;
int main()
{
	int t;cin>>t;
	while(t--)
	{
		cin>>a>>b>>c;
		ll x=min(a,b);
		ll y=max(a,b);
		
		//cout<<x<<' '<<y<<endl;
		if(x==y)
		{
			cout<<"YES"<<endl;
			continue;
		}
		if(x!=y&&c==0)
		{
			cout<<"NO"<<endl;
			continue;
		}
		
		if(x*(c+1)<y) cout<<"NO"<<endl;
		else cout<<"YES"<<endl;
	}
	return 0;	
} 

B - The Cake Is a Lie

题意:给了一个n*m的格子你在(1,1)你要到(n,m)上去 你一共有两种走法 每次向下走你要花x元 每次向左走你要花y元 给了k元问你是否可以刚好把他用完

思路:简单易得从(1,1)到(n,m)上需要花的钱是固定的 就是n*m-1元 k等于这个就输出yes otherwise 输出no

代码如下:

#include<iostream>
using namespace std;

int main()
{
	int t;cin>>t;
	while(t--)
	{
		int n,m,k;
		cin>>n>>m>>k;
		if(k==n*m-1) cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
	}
	return 0;
}

C - Berland Regional

题意:一个学校里有n种队伍 每种队伍都有人且每个人都有技能点 每次派出每种队伍里的(1-n)个人组队(强强联合:技能点多的) 统计一个学校里面可以派出去的队伍的技能点总和

思路:就简单模拟(nn) 但是会超时 所以我们在统计技能点的时候可以采取前缀和的套路 减去每种队伍没有被选上的人的技能点(排序nlogn)每次询问O(1)

代码如下:

#include<iostream>
#include<unordered_set>
#include<vector>
#include<unordered_map>
#include<algorithm>
#define ll long long
using namespace std;
const int N=2e5+10;
unordered_set<int> s;
vector<ll> nums[N];
ll a[N],sum[N];
ll n;

int main()
{
    ll t;cin>>t;
    while(t--)
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            s.insert(a[i]);
        }
        for(int i=1;i<=n;i++)
        {
            int x;cin>>x;
            nums[a[i]].push_back(x);
        }

        for(auto x: s)
        {
            sort(nums[x].begin(),nums[x].end());

            for(int i=1;i<nums[x].size();i++)
                nums[x][i]+=nums[x][i-1];//前缀和
        }
        int v=1;
        while(s.size())
        {
            vector<int> res;
            for(auto x:s)
            {
                int t=nums[x].size();
                int u=t%v;
                ll ss=nums[x].back();//整个容器中的数字和
                if(u>=1) ss-=nums[x][u-1];
                sum[v]+=ss;
                if(v==t) res.push_back(x);
            }
            for(auto x: res) s.erase(x);
            v++;
        }
        for(int i=1;i<=n;i++)
        {
            cout<<sum[i]<<' ';
            nums[i].clear();
            sum[i]=0;
        }
        cout<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值