https://vjudge.net/problem/AtCoder-2565ios
將一個H*W的矩形切成三份,每一次只能水平或者垂直切,問最大塊的面積-最小快的面積 的最小值是多少。c++
先枚舉水平切第一塊的高i,那麼剩餘部分h-i要麼繼續水平切、要麼垂直切,由於要使最大快-最小快 最小,那麼剩下的兩塊確定是相差最少爲好,因此能夠拆成w/2和w-w/2兩塊,也能夠拆成(h-i)/2和(h-i)-(h-i)/2。spa
再枚舉垂直切的第一塊的寬度,後續操做相似。.net
#include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define ll long long const int N=200005; const int mod=1e9+7; const double eps=1e-8; const double PI = acos(-1.0); #define lowbit(x) (x&(-x)) int main() { std::ios::sync_with_stdio(false); ll h,w; while(cin>>h>>w) { ll ans=inf; for(int i=1;i<h;i++) { ll a=h-i; if(i!=h-1) { ans=min(ans,max(i*w,max(a/2*w,(a-a/2)*w))-min(i*w,min(a/2*w,(a-a/2)*w))); } ans=min(ans,max(i*w,max(a*(w/2),a*(w-w/2)))-min(i*w,min(a*(w/2),a*(w-w/2)))); // cout<<i<<" "<<max(i*w,max(a*(w/2),a*(w-w/2)))-min(i*w,min(a*(w/2),a*(w-w/2)))<<" "<<ans<<endl; // cout<<a<<" "<<i<<" "<<w<<" "<<endl; } // cout<<ans<<endl; for(int i=1;i<w;i++) { ll a=w-i; if(i!=w-1) { ans=min(ans,max(i*h,max(a/2*h,(a-a/2)*h))-min(i*h,min(a/2*h,(a-a/2)*h))); } ans=min(ans,max(i*h,max(a*(h/2),a*(h-h/2)))-min(i*h,min(a*(h/2),a*(h-h/2)))); } cout<<ans<<endl; } return 0; }