月赛第一次做上了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; }