Codeforces 1029F Multicolored Markers 【数学】【性质】
要有一个大矩形的面积是a+b,那我们可以枚举这个矩形的所有【短边】,然后枚举面积为a的矩形的所有【短边】,然后看在短边放的进去的时候长边能不能放进去。最后再同样的步骤扫一遍b的短边就行了。
这样会tle,可以加一点贪心。当大矩形的短边确定后,我们不用枚举a矩形的所有短边,我们找到第一个小于等于大矩形短边的短边就行了。【因为这样的话保证短边放的进去,长边最小】
虽然上面的复杂度可以过,但实际上我们可以把这个二分的复杂度也省掉。
因为我们是从小到大枚举大矩形的所有短边,所以对于【a矩形】来说第一个小于等于大矩形的短边只会越来越大,所以我们没必要每次都log复杂度找一次,而是从第一个开始不断向后推就可以了。
#include<bits/stdc++.h> #define INF 1e16+10000 using namespace std; //97821761637600 97821761637600 long long ans=INF; int lenb[1000000],lena[1000000]; int a1,b1; int main(){ ios::sync_with_stdio(false); long long a,b; cin>>a>>b; long long x=a+b; for(long long i=1;i*i<=a;i++) { if(a%i==0){ // cout<<i<<endl; lena[++a1]=i; } } //cout<<"!!!"<<endl; for(long long i=1;i*i<=b;i++) { if(b%i==0) { // cout<<i<<endl; lenb[++b1]=i; } } //cout<<a1<<" "<<b1<<endl; int k1=0,k2=0; for(long long i=1;i*i<=x;i++){ if( x%i==0 ){ while( k1+1<=a1 && lena[k1+1]<=i ) k1++; while( k2+1<=b1 && lenb[k2+1]<=i ) k2++; if( x/i>=a/lena[k1] || x/i>=b/lenb[k2]){ ans = min(ans,2*(i+x/i)); } } } cout<<ans; return 0; }