专栏文章
题解:CF1271F Divide The Students
CF1271F题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mioxd6b4
- 此快照首次捕获于
- 2025/12/03 02:42 3 个月前
- 此快照最后确认于
- 2025/12/03 02:42 3 个月前
提供一种好写的线性做法。
注意到单个和全部是好做的,而两个可以转化为全局加单点减同一个数,于是转化为前两者。枚举总共加的值,计算出所有第二类的取值范围相加检查即可,时间复杂度 。
对边界略加分讨应该可以做到 。
实现。
CPP#include<bits/stdc++.h>
using namespace std;
int l[3],r[3],s[8],P[8]={0,7,3,5,1,6,2,4},a[8],L[8],R[8];
void print(int k){
int res=k;
for(int i=0;i<3;i++) res-=L[i];
for(int i=0;i<3;i++){
res-=(a[(1<<i)^7]=min(res,R[i]-L[i]));
a[(1<<i)^7]+=L[i];
a[1<<i]=max(0,l[i]-k+a[(1<<i)^7]);
}
a[7]=res;
for(int i=1;i<8;i++) printf("%d ",a[P[i]]);printf("\n");
}
inline void solve(){
int sum=0;
for(int i=0;i<3;i++) scanf("%d",&r[i]);
for(int i=0;i<3;i++) scanf("%d",&l[i]);
for(int i=1;i<8;i++) scanf("%d",&s[P[i]]),sum+=(__builtin_popcount(P[i])>1)*s[P[i]];
for(int i=0;i<3;i++){
int sum=0;
for(int j=(1<<i);j<8;j=((j+1)|(1<<i))) sum+=s[j];
l[i]=max(0,sum-l[i]);
if(l[i]>r[i]) return puts("-1"),void();
}
for(int i=0;i<=sum;i++){
int fl=1,suml=0,sumr=s[7];
for(int j=0;j<3;j++){
L[j]=max(0,-(r[j]-i)),R[j]=min(s[(1<<j)^7],s[1<<j]-(l[j]-i));
if(L[j]>R[j]) fl=0;
suml+=L[j],sumr+=R[j];
}
fl&=(suml<=i&&i<=sumr);
if(!fl) continue;
return print(i);
}
puts("-1");
}
signed main(){
signed T=1;
scanf("%d",&T);
while(T--) solve();
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...