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;
}