日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

BZOJ 1859 Luogu P2589 [ZJOI2006]碗的叠放 (计算几何)

發(fā)布時(shí)間:2025/3/15 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ 1859 Luogu P2589 [ZJOI2006]碗的叠放 (计算几何) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

woc, 13年前的ZJOI就這么毒瘤的嘛。。。

題目鏈接: (bzoj)https://www.lydsy.com/JudgeOnline/problem.php?id=1859

(luogu)https://www.luogu.org/problemnew/show/P2589

題解: 大分類(lèi)討論,預(yù)處理\(ints[i][j]\)表示碗\(i\)疊在\(j\)上,\(i\)的底部比\(j\)的底部要高多少

然后分類(lèi)討論求此數(shù)組:

(1) \(i\)的下半徑比\(j\)的上半徑大,則等于\(j\)的高度

(2) \(i\)的上半徑比\(j\)的下半徑小,則等于零

(3) \(i\)的碗壁斜率大于\(j\)的碗壁斜率

(3.1) 若\(i\)的下半徑小于等于\(j\)的下半徑,則為零

(3.2) 若\(i\)的下半徑大于\(j\)的下半徑,則接觸點(diǎn)橫坐標(biāo)為\(i\)的下半徑,通過(guò)\(j\)的一次函數(shù)計(jì)算高度即可

(4) \(i\)的碗壁斜率小于\(j\)的碗壁斜率

(4.1) 若\(i\)的上半徑大于等于\(j\)的上半徑,則接觸點(diǎn)為\(j\)的口處,通過(guò)\(i\)的一次函數(shù)計(jì)算高度

(4.2) 若\(i\)的上半徑小于\(j\)的上半徑,則(不妨先不考慮碗底)接觸點(diǎn)橫坐標(biāo)為\(i\)的上半徑,通過(guò)\(j\)的一次函數(shù)計(jì)算高度

情況(4)最后求出來(lái)的高度和\(0\)取Max.

(5) 若\(i\)\(j\)碗壁斜率相等

(5.1) 若\(i\)的下半徑小于等于\(j\)的下半徑,則高度為\(0\).

(5.2) 若\(i\)的下半徑大于\(j\)的上半徑,則接觸點(diǎn)橫坐標(biāo)為\(i\)的下半徑,通過(guò)一次函數(shù)計(jì)算高度即可。

然后一個(gè)顯然的性質(zhì)是一個(gè)碗疊在一摞碗上,它的疊放高度為和每個(gè)碗分別疊放的高度的Max.

這題……我還能說(shuō)什么呢23333

代碼

#include<cstdio> #include<cstdlib> #include<cstring> #include<cassert> #include<algorithm> using namespace std;const int N = 9; struct Element {int h,r1,r2;double calc(double x) {return h*(x-(double)r1)/((double)r2-r1);} } a[N+3]; double hh[N+3]; int permu[N+3]; double ints[N+3][N+3]; int n;double intersect(int x,int y) { // printf("Intersect (%d,%d)\n",x,y);double ret;if(a[x].r1>a[y].r2) {ret = a[y].h;/* printf("Case 1\n");*/}else if(a[x].r2<a[y].r1) {ret = 0;/* printf("Case 2\n");*/}else if((a[y].r2-a[y].r1)*a[x].h>(a[x].r2-a[x].r1)*a[y].h){if(a[x].r1<=a[y].r1) {ret = 0;/* printf("Case 3.1\n");*/}else {ret = a[y].calc((double)a[x].r1);/* printf("Case 3.2\n");*/}}else if((a[y].r2-a[y].r1)*a[x].h<(a[x].r2-a[x].r1)*a[y].h){if(a[x].r2>=a[y].r2) {ret = a[y].h-a[x].calc(a[y].r2);/* printf("Case 4.1\n");*/} // else if(a[x].h*(a[y].r2-a[y].r1)<=a[y].h*(a[x].r2-a[y].r1)) {ret = 0;}else {ret = a[y].calc(a[x].r2)-a[x].calc(a[x].r2);/* printf("Case 4.2\n");*/}if(ret<0) ret = 0;}else{if(a[x].r1<=a[y].r1) {ret = 0;/* printf("Case 5.1\n");*/}else {ret = a[y].calc(a[x].r1);/* printf("Case 5.2\n");*/}} // printf("ret=%lf\n",ret);return ret; }double calc() { // printf("calc: "); for(int i=1; i<=n; i++) printf("%d ",permu[i]); puts("");double ret = 0.0;for(int i=1; i<=n; i++){hh[i] = 0;for(int j=1; j<i; j++){hh[i] = max(hh[i],hh[j]+ints[permu[i]][permu[j]]);}ret = max(ret,hh[i]+a[permu[i]].h);} // printf("Total=%lf\n",ret); puts("");return ret; }int main() {scanf("%d",&n);for(int i=1; i<=n; i++) scanf("%d%d%d",&a[i].h,&a[i].r1,&a[i].r2);for(int i=1; i<=n; i++) permu[i] = i;for(int i=1; i<=n; i++){for(int j=1; j<=n; j++){if(i==j) continue;ints[i][j] = intersect(i,j);}}double ans = 1e6;do{ans = min(ans,calc());} while(next_permutation(permu+1,permu+n+1));printf("%d\n",(int)(ans+0.5));return 0; }

總結(jié)

以上是生活随笔為你收集整理的BZOJ 1859 Luogu P2589 [ZJOI2006]碗的叠放 (计算几何)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。