月赛第一次做上了5题!!放上来纪念一下,一道超级细心的分类讨论题,只有你想不到的情况。。。
做之前最好先自己想一会儿,总结出点什么贪心的思想。。。
#include<bits/stdc++.h>
#define mod 1000000007
#define ll unsigned long long
using namespace std;
int main(){
int t;
scanf("%d",&t);
while(t--){
ll n,m,z,a,b,c;
cin>>n>>m>>z>>a>>b>>c;
ll s=z+a+b+c;
if(z+a+b>=n*m){
cout<<n*m<<endl;
continue;
}
if(m==1){
cout<<min(s,n*m)<<endl;
continue;
}
else if(m==2){
if(a+b<=n){
ll p=min(c,n);
cout<<a+b+p+min(z,n*m-a-b-p)<<endl;
}
else{
cout<<min(n*m,s)<<endl;
}
continue;
}
if(m%2==1){
ll s1=min(n,(a+b)/(m-1)); //aaa_bbbb 可以有几行
ll s2=m,s3=0;
if(s1<n){
s2=(a+b)%(m-1);
s3=max(0ull,n-s1-1);
if(s2==0){
s2=m;
s3++;
}
}
s2=m-s2;
s1-=max(0ull,a+b-n*(m-1));//可能左侧填满还有多余,就把s1最右列给占了
ll ss=min(s1,c+z); //用c和z取填s1最右列
c-=ss;
if(c<0){
z-=-c;
c=0;
}
ss+=a+b;
ll f=min(c,s2/2+s2%2+s3*(m/2+m%2)); //c填s2和s3
ss+=f;
ss+=min(z,max(0ull,n*m-min(n*m,a+b+min(n,(a+b)/(m-1)))-f));//z填s2和s3
cout<<ss<<endl;
}
else{ //偶数的时候,有一列对于c是多余的,所以尽量填满
if(a+b<=n){
ll p=min(c,m/2*n);
cout<<a+b+p+min(z,n*m-a-b-p)<<endl;
}
else{
a-=n;
if(a<0){
b-=-a;
a=0;
}
m--;
ll s1=min(n,(a+b)/(m-1)); //aaa_bbbb 可以有几行
ll s2=m,s3=0;
if(s1<n){
s2=(a+b)%(m-1);
s3=max(0ull,n-s1-1);
if(s2==0){
s2=m;
s3++;
}
}
s2=m-s2;
s1-=max(0ull,a+b-n*(m-1));//可能左侧填满还有多余,就把s1最右列给占了
ll ss=min(s1,c+z); //用c和z取填s1最右列
c-=ss;
if(c<0){
z-=-c;
c=0;
}
ss+=a+b;
ll f=min(c,s2/2+s2%2+s3*(m/2+m%2)); //c填s2和s3
ss+=f;
ss+=min(z,max(0ull,n*m-min(n*m,a+b+min(n,(a+b)/(m-1)))-f));
cout<<ss+n<<endl;
}
}
}
return 0;
}