bzoj1011: [HNOI2008]遥远的行星
这题好神,完全接受不能啊;
在看题解之前,我千方百计想着怎么精确地算出结果,但苦思之后决定看题解,没想到题解是估计近似;
个人题解:题目中的要求是结果误差不能超过5%,这个条件很关键;
可以设置一个范围,在这个范围之内精确计算,超过这个范围就近似;
虽然我的感觉是很可能被卡(我想的是有可能通过1 1 1 1000000 1 1 1这样的方式卡掉),
但实际上AC了,所以在考试时要大胆的假设,这种估算法在某些题比较关键;
代码其实都类似:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<cstdlib> 6 #include<ctime> 7 #include<vector> 8 #include<algorithm> 9 #include<queue> 10 #include<map> 11 #include<vector> 12 #include<cmath> 13 using namespace std; 14 #define LL long long 15 #define up(i,j,n) for(int i=j;i<=n;i++) 16 #define down(i,n,j) for(int i=n;i>=j;i--) 17 const double eps=1e-8; 18 const int maxn=101000; 19 int n; 20 double m[maxn],A,f[maxn],pre[maxn]; 21 void init(){ 22 freopen("1.in","r",stdin); 23 freopen("1.out","w",stdout); 24 scanf("%d%lf",&n,&A); 25 up(i,1,n)scanf("%lf",&m[i]); 26 } 27 void work(){ 28 int T=20; 29 for(int i=1;i<=T;i++){ 30 int t=(int)(eps+floor(A*i)); 31 for(int j=1;j<=t;j++)f[i]+=m[j]/(i-j)*m[i]; 32 } 33 for(int i=T+1;i<=n;i++){ 34 int r=(int)(eps+floor(A*i)); 35 int l=(int)(eps+floor(A*(i-T))); 36 for(int j=l+1;j<=r;j++)f[i]+=m[j]*m[i]/(i-j); 37 f[i]+=m[i]*(f[i-T]/m[i-T])*(i-T-1.0*l/2)/(i-1.0*l/2); 38 } 39 up(i,1,n)printf("%.6lf\n",f[i]); 40 } 41 int main(){ 42 init(); 43 work(); 44 }