[Codeforces 163D]Large Refrigerator (DFS+剪枝)

博客围绕Codeforces 163D题展开,已知长方体体积V(以质因数分解形式给出),三边长为正整数,求最小表面积S。先提出暴力做法,接着从搜索顺序、可行性剪枝、最优化剪枝、常数优化等方面进行优化,还指出易错点,最后给出代码来源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[Codeforces 163D]Large Refrigerator (DFS+剪枝)

题面

已知一个长方体的体积为V,三边长a,b,c均为正整数,求长方体的最小表面积S

V以质因数分解的形式给出

分析

暴力做法很容易想到,按照质因子的指数枚举a,b,然后就能直接算出c,然后就可以得到表面积S=2(ab+bc+ac)

考虑优化:

1.搜索顺序:保证\(a \geq b \geq c\),枚举质因数时从大到小枚举a,从小到大枚举b

2.可行性剪枝:枚举a的时候保证\(a^3 \leq V\),枚举b时保证\(ab^2 \leq V\)

3.最优化剪枝:发现\(S=2(ab+bc+ac)=2a(b+c)+2bc\),又因为\(bc=\frac{V}{a}\),\(S=2a(b+c)+\frac{2V}{a}\)。根据基本不等式有\(b+c \geq 2 \sqrt{bc}=2\sqrt{\frac{V}{a}}\).所以枚举a的时候判断若\(\frac{2V}{a}+4a\sqrt{\frac{V}{a}}\)比当前答案大,就不要再继续搜索b了

4.常数优化:快读快写,预处理质因数的i次方

5.易错点:a,b,c的乘积可能会爆long long,要转成double再判断

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 100
#define rg register
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
inline void qread(int &x) {
    x=0;
    int sign=1;
    char c=getchar();
    while(c<'0'||c>'9') {
        if(c=='-') sign=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9') {
        x=x*10+c-'0';
        c=getchar();
    }
    x=x*sign;
}
inline void qprint(int x) {
    if(x<0) {
        putchar('-');
        qprint(-x);
    } else if(x==0) {
        putchar('0');
        return;
    } else {
        if(x/10>0) qprint(x/10);
        putchar(x%10+'0');
    }
}
inline void qread(ll &x) {
    x=0;
    int sign=1;
    char c=getchar();
    while(c<'0'||c>'9') {
        if(c=='-') sign=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9') {
        x=x*10+c-'0';
        c=getchar();
    }
    x=x*sign;
}
inline void qprint(ll x) {
    if(x<0) {
        putchar('-');
        qprint(-x);
    } else if(x==0) {
        putchar('0');
        return;
    } else {
        if(x/10>0) qprint(x/10);
        putchar(x%10+'0');
    }
}
inline ll fast_pow(ll x,ll k){
    ll ans=1;
    while(k){
        if(k&1) ans=ans*x;
        x=x*x;
        k>>=1;
    }
    return ans;
}
 
int t,n;
ll V;
ll p[maxn+5];
ll k[maxn+5];
ll mpow[maxn+5][maxn+5];
ll ans=INF;
ll ansa,ansb,ansc;
ll maxa;
void dfsb(int deep,ll va,ll vb){
    if((double)va*vb*vb>V) return;
    if(deep>n){
        ll vc=V/va/vb;
        if(2*(va*vb+va*vc+vb*vc)<ans){
            ans=2*(va*vb+va*vc+vb*vc);
            ansa=va;
            ansb=vb;
            ansc=vc;
        }
        return;
    }
    for(rg int i=0;i<=k[deep];i++){
        k[deep]-=i;
        dfsb(deep+1,va,vb*mpow[deep][i]);
        k[deep]+=i;
    }
}
void dfsa(int deep,ll va){
    if((double)va*va*va>V) return;
    if(deep>n){
        double mins=2.0*V/va+4.0*va*sqrt(1.0*V/va);
        if(mins>1.0*ans) return; //最优化剪枝 
        //S=2(ab+bc+ac)=2a(b+c)+2V/a
        //由基本不等式得b+c>=2sqrt(bc)
        //S>=2a*2sqrt(V/a)+2V/a
        dfsb(1,va,1); 
        return;
    } 
    for(rg int i=k[deep];i>=0;i--){
        k[deep]-=i;
        dfsa(deep+1,va*mpow[deep][i]);
        k[deep]+=i;
    }
}
 
int main(){
//  freopen("1.in","r",stdin);
//  freopen("1.out","w",stdout);
    qread(t);
    while(t--){
        qread(n);
        V=1;
        for(int i=1;i<=n;i++){
            qread(p[i]);
            qread(k[i]);
//          V*=fast_pow(p[i],k[i]);
        }
        for(int i=1;i<=n;i++){
            mpow[i][0]=1;
            for(int j=1;j<=k[i];j++){
                mpow[i][j]=mpow[i][j-1]*p[i];
            }
            V*=mpow[i][k[i]];
        }
        ans=INF;
        dfsa(1,1);
        qprint(ans);
        putchar(' '); 
        qprint(ansa);
        putchar(' '); 
        qprint(ansb);
        putchar(' '); 
        qprint(ansc);
        putchar('\n'); 
    }
} 

转载于:https://www.cnblogs.com/birchtree/p/11185672.html

当前提供的引用内容并未提及关于Codeforces比赛M1的具体时间安排[^1]。然而,通常情况下,Codeforces的比赛时间会在其官方网站上提前公布,并提供基于不同时区的转换工具以便参赛者了解具体开赛时刻。 对于Codeforces上的赛事而言,如果一场名为M1的比赛被计划举行,则它的原始时间一般按照UTC(协调世界时)设定。为了得知该场比赛在UTC+8时区的确切开始时间,可以遵循以下逻辑: - 前往Codeforces官网并定位至对应比赛页面。 - 查看比赛所标注的标准UTC起始时间。 - 将此标准时间加上8小时来获取对应的北京时间(即UTC+8)。 由于目前缺乏具体的官方公告链接或者确切日期作为依据,无法直接给出Codeforces M1比赛于UTC+8下的实际发生时段。建议定期访问Codeforces平台查看最新动态更新以及确认最终版程表信息。 ```python from datetime import timedelta, datetime def convert_utc_to_bj(utc_time_str): utc_format = "%Y-%m-%dT%H:%M:%SZ" bj_offset = timedelta(hours=8) try: # 解析UTC时间为datetime对象 utc_datetime = datetime.strptime(utc_time_str, utc_format) # 转换为北京时区时间 beijing_time = utc_datetime + bj_offset return beijing_time.strftime("%Y-%m-%d %H:%M:%S") except ValueError as e: return f"错误:{e}" # 示例输入假设某场Codeforces比赛定于特定UTC时间 example_utc_start = "2024-12-05T17:35:00Z" converted_time = convert_utc_to_bj(example_utc_start) print(f"Codeforces比赛在北京时间下将是:{converted_time}") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值