北京大学ACM/ICPC竞赛训练暑期课练习之泰国佛塔

来源:互联网 发布:c语言if flag 编辑:程序博客网 时间:2024/04/28 04:31
#include<iostream>#include<cstring>#include<cmath>#include<vector>using namespace std;int plies,volume;int minA = 1 << 30;int area = 0; //正在搭建中的表面积int minarea[21]; //n层最少面积int minvolume[21]; //n层最少体积void DFS(int v,int p,int r,int h)//最底层半径不能超过r,高度不能超过h{    if(p == 0){        if(v) return;        else{            minA = min(minA,area);        }    }    if(v <= 0) return;    if(minvolume[p] > volume) return;    if(area + minarea[p] >= minA) return;    if(2*v/r + area >= minA) return; // very important!!!    if(h < p || r < p) return;    for(int rr = r;rr >= p;rr--){        if(p == plies)            area = rr * rr;        for(int hh = h;hh >= p;hh--){            area += 2 * rr * hh;            DFS(v - rr * rr * hh,p - 1,rr - 1,hh - 1);            area -= 2 * rr * hh;        }    }}int main(){    while(cin>>volume>>plies){        minvolume[0] = 0;        minarea[0] = 0;        for(int i = 1;i <= plies;i++){            minvolume[i] = minvolume[i-1] + i * i * i;//第i层半径、高度至少i            minarea[i] = minarea[i-1] + 2 * i * i;        }        if(minvolume[plies]>volume) cout<<0<<endl;        else{            area = 0;            minA = 1 << 30;            int maxHeight = (volume - minvolume[plies-1]) / (plies*plies) + 1;            int maxRadius = sqrt(double(volume-minvolume[plies-1]) / plies) + 1;            DFS(volume,plies,maxRadius,maxHeight);            if(minA == 1 << 30)                cout<<0<<endl;            else                cout<<minA<<endl;        }    }    return 0;}

0 0
原创粉丝点击