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;    
}

 

posted @ 2018-09-02 08:49  4397  阅读(259)  评论(0编辑  收藏  举报