题目大意:
给你 a个红块 b个蓝块 拼成一个实心矩形,并且要求红块或者蓝块自成一个矩形,问形成的这个矩形最小的周长是多少。

#include <iostream> #include <cstdio> #include <algorithm> #include <queue> #include <stack> #include <bitset> #include <vector> #include <map> #include <string> #include <cstring> #include <bitset> #define inf 0x3f3f3f3f #define inf64 0x3f3f3f3f3f3f3f3f using namespace std; const int maxn=2e5+10; typedef long long ll; vector<pair<ll,ll>>G[3]; ll a,b; void init(){ ll sum=a+b; for(ll i=1;i*i<=sum;i++){ if(sum%i==0){ G[0].push_back(make_pair(i,sum/i)); } } for(ll i=1;i*i<=a;i++){ if(a%i==0){ G[1].push_back(make_pair(i,a/i)); } } for(ll i=1;i*i<=b;i++){ if(b%i==0){ G[2].push_back(make_pair(i,b/i)); } } } bool check(int num,int u,ll x){ if(G[num][u].first<=x) return true; return false; } int main(){ scanf("%lld%lld",&a,&b); init(); ll ans=inf64; for(int i=0;i<G[0].size();i++){ ll len=G[0][i].first; int l=0,r=G[1].size()-1,res=-1; while(l<=r){ int mid=(l+r)>>1; if(check(1,mid,len)) l=mid+1,res=mid; else r=mid-1; } if(res!=-1&&G[0][i].second>=G[1][res].second) ans=min(ans,2*(G[0][i].first+G[0][i].second)); } for(int i=0;i<G[0].size();i++){ ll len=G[0][i].first; int l=0,r=G[2].size()-1,res=-1; while(l<=r){ int mid=(l+r)>>1; if(check(2,mid,len)) l=mid+1,res=mid; else r=mid-1; } if(res!=-1&&G[0][i].second>=G[2][res].second) ans=min(ans,2*(G[0][i].first+G[0][i].second)); } printf("%lld ",ans); return 0; }