ACM-ICPC 2015 Asia Tsukuba Regional Online Open Contest B(兩擋板之間放著圓球,求擋板最短距離)
阿新 • • 發佈:2019-02-11
一開始想得很麻煩,然後發現又讀漏了可以簡化題目的資訊……好不容易想到的方法一定要記錄一下。。。
#include<iostream> #include<algorithm> #include<string> #include<map>//ll dx[4]={0,0,-1,1};ll dy[4]={-1,1,0,0}; #include<set>// #include<vector> #include<cmath> #include<stack> #include<string.h> #include<stdlib.h> #include<cstdio> #define mod 1e9+7 #define ll long long using namespace std; double y[1010];//存每個球的中心的座標 double x[1010]; int main(){ int n; cin>>n; for(int i=0;i<n;++i) cin>>x[i]; double s=0; if(n==1){ printf("%.6f\n",2*x[0]); return 0; } y[0]=x[0]; for(int i=1;i<n;++i){ double g=sqrt((x[i]+x[i-1])*(x[i]+x[i-1])-(x[i]-x[i-1])*(x[i]-x[i-1])); double p=y[i-1]+g; //先算出這個球對於前一個球的最佳擺放座標 for(int j=i-2;j>=0;--j){ g=sqrt((p-y[j])*(p-y[j])+(x[i]-x[j])*(x[i]-x[j])); if(g<x[i]+x[j]){ //判斷球擺放在這裡會不會和之前的球有衝突重疊 double h=sqrt((x[i]+x[j])*(x[i]+x[j])-(x[i]-x[j])*(x[i]-x[j])); p=max(p,y[j]+h); } } y[i]=max(p,x[i]); //這裡還要注意和自身的半徑比較 } double maxx=0; for(int i=0;i<n;++i){ maxx=max(maxx,y[i]+x[i]); //【球的座標+它的半徑】最大值就是擋板之間的距離 } printf("%.6f\n",maxx); return 0; }