zoukankan      html  css  js  c++  java
  • [bzoj1011](HNOI2008)遥远的行星(近似运算)

    Description

    直 线上N颗行星,X=i处有行星i,行星J受到行星I的作用力,当且仅当i<=AJ.此时J受到作用力的大小为 Fi->j=Mi*Mj/(j-i) 其中A为很小的常量,故直观上说每颗行星都只受到距离遥远的行星的作用。请计算每颗行星的受力,只要结果的相对误差不超过5%即可.

    Input

    第一行两个整数N和A. 1<=N<=10^5.0.01< a < =0.35
    接下来N行输入N个行星的质量Mi,保证0<=Mi<=10^7

    Output

    N行,依次输出各行星的受力情况

    Sample Input

    5 0.3
    3
    5
    6
    2
    4

    Sample Output

    0.000000
    0.000000
    0.000000
    1.968750
    2.976000

    HINT

    精确结果应该为0 0 0 2 3,但样例输出的结果误差不超过5%,也算对。

    分析

        乍一看这似乎是一道不可做题…… $O(alpha N^2)$的复杂度,大概再怎么卡常数也是过不了吧?别急……我们看一下这句话……“答案误差不超过5%即可”。瞬间变水题啊好吗……

        考虑到j-i足够大时相邻一定范围内的$frac{1}{j-i}$相差很小,我们可以随便选一个i来计算j-i,把它作为分母计算一定范围内的i星球对j产生的合力。

        具体地,我们可以随便计算出一个需要精确计算的范围$delta$,对距离大于这个范围的星球统一计算合力即可。

     1 /**************************************************************
     2     Problem: 1011
     3     User: AsmDef
     4     Language: C++
     5     Result: Accepted
     6     Time:1656 ms
     7     Memory:2308 kb
     8 ****************************************************************/
     9  
    10 #include <cctype>
    11 #include <cstdio>
    12 #include <cmath>
    13 #include <cstdlib>
    14 using namespace std;
    15 template<typename T>inline void getd(T &x){
    16     char c = getchar(); bool minus = 0;
    17     while(!isdigit(c) && c != '-')c = getchar();
    18     if(c == '-')minus = 1, c = getchar();
    19     x = c - '0';
    20     while(isdigit(c = getchar()))x = x * 10 + c - '0';
    21     if(minus)x = -x;
    22 }
    23 /*========================================================*/
    24 const int maxn = 100002;
    25 const double eps = 1e-12;
    26 int N;
    27 int main(){
    28      
    29     //#undef DEBUG
    30      
    31     double A, M[maxn], S[maxn];
    32     #if defined DEBUG
    33     freopen("test""r", stdin);
    34     freopen("out.txt""w", stdout);
    35     #else
    36     //freopen("bzoj_1011_planet.in", "r", stdin);
    37     //freopen("bzoj_1011_planet.out", "w", stdout);
    38     #endif
    39     getd(N);
    40     int i, j, t, s;
    41     double Ans, mid;
    42     scanf("%lf", &A);
    43     double lim = 1 / A;
    44     S[0] = 0;
    45     for(i = 1;i <= N;++i)
    46         scanf("%lf", M + i), S[i] = S[i-1] + M[i];
    47     printf("%.6lf ", (double)0);
    48     for(i = 2;i <= N;++i){
    49         Ans = 0;
    50         t = (int)(i * A + eps);
    51         s = (int)(t - lim);
    52         if(s > 1){
    53             mid = (int)sqrt((double)(i-1) * (i-s+1));
    54             Ans += M[i] * S[s-1] / mid;
    55         }
    56         else s = 1;
    57         for(j = s;j <= t;++j)
    58             Ans += M[i] * M[j] / (i - j);
    59         printf("%.6lf ", Ans + eps);
    60     }
    61      
    62     return 0;
    63 }
    数值近似
  • 相关阅读:
    xml
    企业级应用和互联网应用的区别
    javaee学习目标
    数据库基本原理
    数据库学习感想
    数据库设计
    团队项目自我评价
    团队项目-软件度量
    团队项目-初级版本
    团队项目—详细设计
  • 原文地址:https://www.cnblogs.com/Asm-Definer/p/4369460.html
Copyright © 2011-2022 走看看