zoukankan      html  css  js  c++  java
  • bzoj 1011[HNOI2008]遥远的行星

    1011: [HNOI2008]遥远的行星

    Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special Judge

    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%,也算对

    这题还算是比较神的

    因为精度误差范围很大

    所以对于i很大的情况, 我们会发现 上界的 (i - A * j) 和 下界的(i - 1) 其实相对的差不是很大

    所以我们就直接得到了答案

    $$ANS = frac{M[i] * sum_{1}^{j}M[j]}{i - frac{j}{2}}$$

    小数据暴力, 大数据 近似

    然而依旧很玄学 ~

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #define LL long long
     5 
     6 using namespace std;
     7 const int MAXN = 5e5 + 10;
     8 const double eps = 1e-8;
     9 int N;
    10 double sum[MAXN];
    11 double M[MAXN], A;
    12 inline LL read()
    13 {
    14     LL x = 0, w = 1; char ch = 0;
    15     while(ch < '0' || ch > '9') {
    16         if(ch == '-') {
    17             w = -1; 
    18         } 
    19         ch = getchar();
    20     }
    21     while(ch >= '0' && ch <= '9') {
    22         x = x * 10 + ch - '0';
    23         ch = getchar();
    24     }
    25     return x * w;
    26 }
    27 int main()
    28 {
    29 //    freopen("planet10.in", "r", stdin);
    30 //    freopen("t.out", "w", stdout);
    31     N = read();
    32     scanf("%lf", &A);
    33     for(int i = 1; i <= N; i++) {
    34         scanf("%lf", &M[i]);
    35         sum[i] = sum[i - 1] + M[i];
    36     }
    37     if(N <= 3000) {
    38         for(int i = 1; i <= N; i++) {
    39             double ans = 0;
    40             int m = (int)(A * (double)i + eps);
    41             for(int j = 1; j <= m; j++) {
    42                 ans += M[i]* M[j] / (i - j);
    43             }
    44             printf("%lf
    ", ans);
    45         }
    46     } else {
    47         double ans;
    48         for(int i = 1; i <= 3000; i++) {
    49             ans = 0;
    50             int m = (int)(A * (double)i + eps);
    51             for(int j = 1; j <= m; j++) {
    52                 ans += M[i]* M[j] / (i - j);
    53             }
    54             printf("%lf
    ", ans);
    55         }
    56         for(int i = 3000 + 1; i <= N; i++) {
    57             int m = (int)(A * (double)i + eps);
    58             ans = M[i] * sum[m] / (double)(i - m / 2);
    59             printf("%lf
    ", ans);
    60         }
    61     }    
    62 //    fclose(stdin);
    63 //    fclose(stdout);
    64     return 0;
    65 }
    66 
    67 /*
    68 5 0.3
    69 
    70 3
    71 
    72 5
    73 
    74 6
    75 
    76 2
    77 
    78 4
    79 */
    View Code
  • 相关阅读:
    OpenJudge计算概论-四大湖
    OpenJudge计算概论-排队游戏【这个用到了栈的思想】
    OpenJudge计算概论-流感传染【这个题用二维数组】
    OpenJudge计算概论-扩号匹配问题【这个用到了栈的思想】
    Openjudge计算概论-角谷猜想
    OpenJudge计算概论-发票统计
    OpenJudge计算概论-Tomorrow never knows【输入日期计算下一天的日期】
    已知二叉树的中序和前序序列(或后序)求解树
    OpenJudge计算概论-寻找下标
    OpenJudge计算概论-校门外的树
  • 原文地址:https://www.cnblogs.com/wuenze/p/8398159.html
Copyright © 2011-2022 走看看