Educational Codeforces Round 108 (Rated for Div. 2) A-D

Educational Codeforces Round 108 (Rated for Div. 2)

A. Red and Blue Beans

题意:有红豆r个,蓝豆b个,每次分配 r i r_i ri个红豆和 b i 个 蓝 豆 b_i个蓝豆 bi打包且保证 r i 和 b i r_i和b_i ribi都大于等于1且保证 ∣ r i − b i ∣ < = d |r_i-b_i|<=d ribi<=d,问能否恰好把所有红豆蓝豆打包完
题解:极端的假设,保证r<b的情况下,当 r i = 1 r_i=1 ri=1时, b i < = d + 1 b_i<=d+1 bi<=d+1,每次最多可以减少 d d d的差值,所以只要保证 b − r < = d ∗ r b-r<=d*r br<=dr;在r>=b情况下同理。

//#pragma GCC optimize(2)
#include<bits/stdc++.h> 
using namespace std;
#define endl "\n" 
#define ll long long
signed main(){
    ios_base::sync_with_stdio(0);cin.tie(0),cout.tie(0);
    int t;cin>>t;
    while(t--){
        ll r,b,d;cin>>r>>b>>d;
        ll mi=min(r,b)*d;
        if(abs(r-b)>mi)cout<<"NO"<<endl;
        else cout<<"YES"<<endl;
    }
   return 0;
} 

B. The Cake Is a Lie

题意:矩阵,往右(x,y+1)走则权值加上横坐标x,往下走(x+1,y)则权值加上纵坐标y,问从(1,1)出发达到(n,m)的权值是不是K?
题解:可以手算确定,到达每个点的权值是一定即n-1+n*(m-1)

//#pragma GCC optimize(2)
#include<bits/stdc++.h> 
using namespace std;
#define endl "\n" 
#define ll long long
signed main(){
    ios_base::sync_with_stdio(0);cin.tie(0),cout.tie(0);
    int t;cin>>t;
    while(t--){
        ll n,m,k;cin>>n>>m>>k;
        if(n-1+n*(m-1)==k)cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
   return 0;
} 

C. Berland Regional

题意:n个学生,分别来自学校 u i u_i ui,且每个学生都有编程能力 s i s_i si。每个学校每次选择学生组成一个k人的队伍参赛时,都让 s i s_i si较大的k个人组在一起,同个学校可以派出多个队伍且保证每个队友恰好有k个人。问k=1,2,3…n时,求出所有学校派出学生组队参赛的所有 ∑ s i \sum{s_i} si
题解:把每个学生存到对应的学校,并按照从大到小降序存进数组u[],且对每个学校的该大小位size的数组进行前缀和s[],每个学校对 a n s k ans_k ansk的贡献是前size-k%size个的前缀和

//#pragma GCC optimize(2)
#include<bits/stdc++.h> 
using namespace std;
#define endl "\n" 
#define ll long long
const int N=2e5+7;
set<ll>st;
vector<ll>u[N];
bool cmp(pair<ll,ll>a,pair<ll,ll>b){
	return a.first>b.first;
}
signed main(){
    ios_base::sync_with_stdio(0);cin.tie(0),cout.tie(0);
    int t;cin>>t;
    while(t--){
        int n;cin>>n;
		vector<pair<ll,ll>>p(n); 
		vector<ll>ans(n+2,0); st.clear();
		for(int i=0;i<n+1;i++)u[i].clear(); 
		for(int i=0;i<n;i++)cin>>p[i].second,st.insert(p[i].second);
		for(int i=0;i<n;i++)cin>>p[i].first;
		sort(p.begin(),p.end(),cmp);
		for(int i=0;i<n;i++)u[p[i].second].push_back(p[i].first);
		for(auto i:st){
			int siz=u[i].size();
			for(int j=1;j<siz;j++)u[i][j]+=u[i][j-1];
			for(int j=1;j<=siz;j++)ans[j]+=u[i][siz-1-siz%j];//关键是这里处理ans[]
		}
		for(int i=1;i<=n;i++)cout<<ans[i]<<" ";
		cout<<endl;
    }
   return 0;
} 

D. Maximum Sum of Products

题意:可以至多反转一次a[],问最大的 ∑ a i ∗ b i \sum{a_i*b_i} aibi
题解:T=2s,n=5000,直接枚举所有情况,所以考虑ai*bi的前缀和,枚举中点,且考虑翻转的长度奇偶,把翻转的[l,r]和[l-1,r+1]的式子展开发展不同点只有a[l-1]*b[r+1]+a[r+1]*b[l-1],左右两端用前缀和求和即可

//#pragma GCC optimize(2)
#include<bits/stdc++.h> 
using namespace std;
#define endl "\n" 
#define ll long long
ll a[5005],b[5005],s[5005],ans=0;
int n;
void run1(int x){ //翻转长度位奇数
    ll res=0;
    for(int l=x,r=x;l>=1&&r<=n;l--,r++){
        if(l==r) res+=a[l]*b[l];
        else res+=a[l]*b[r]+a[r]*b[l];
        ans=max(ans,res+s[l-1]+s[n]-s[r]);
    }
}
void run2(int x){  //翻转长度位偶数
    ll res=0;
    for(int l=x,r=x+1;l>=1&&r<=n;l--,r++){
        if(l==r) res+=a[l]*b[l];
        else res+=a[l]*b[r]+a[r]*b[l];
        ans=max(ans,res+s[l-1]+s[n]-s[r]);
    }
}
signed main(){
    ios_base::sync_with_stdio(0);cin.tie(0),cout.tie(0);
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int j=1;j<=n;j++)cin>>b[j];
    for(int i=1;i<=n;i++)s[i]=s[i-1]+a[i]*b[i];
    for(int i=1;i<=n;i++)run1(i); //翻转长度位奇数
    for(int i=1;i<=n;i++)run2(i); //翻转长度位偶数
    ans=max(ans,s[n]); //特判一下原来不翻转
    cout<<ans;
   return 0;
} 
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值