• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

会点儿code

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

2007 ACM南京预赛C题

Ray’s Magic Ball

时间限制(普通/Java):1000MS/3000MS          运行内存限制:65536KByte
总提交:554            测试通过:95

描述

Ray has just borrowed the Magic Ball (MB) from Jiejie. The Magic Ball is a hollow metal ball whose thickness can be ignored. Although it is called Magic Ball, Jiejie still has no idea where the magic lies. Therefore, he sincerely asked Ray to demonstrate it in return for his lending.

It was a really long time before Ray has come up with an idea. First, he finds a way to fill the ball with a sort of liquid, then he hangs it in the air, and at the last and the most important step, he makes a small hole right at the bottom of the ball (the lowest point on the ball after its being hung). As you can imagine, the liquid begins to leak. Now Ray announced proudly, “God has told me of the depth of the remaining liquid when the center of the gravity of the whole ball (including the liquid) is lowest”. Can you also do it?

 

输入

The input contains multiple test cases. For each test case, there is only one line containing three integers (all less than 30000), representing the radius of the ball, the mass of the ball and the density of the liquid respectively.


输出

For each test case output one number indicating the depth of the remaining liquid, and output two digits after the decimal point.


样例输入

1 0 10000

样例输出

0.00

题目来源

NUAA


        写这题主要不是为了讲题目的解法,而是借此机会回顾一下高数里积分的知识。
当时网络赛这题没解出来,后来除了我们做出的3道外,这道AC的人数最多,所以也来试试。
 
【题目大意】
        一个球,里面装了液体,球的下放有个洞,所以液体会从下面漏出去。
问当液体漏到高度为多少时整个球的重心最低,结果小数点后取两位。以知条件:球半径,球质量,液体密度。
 
【解题思路】
        取所有可能的液体高度,比较出一个重心最小的位置。这样做无疑风险比较大,因为半径<30000,步进为0.01,最坏情况下要比较的点数为3*10^6,数据一多恐怕就TLE了。但是最后做为尝试性的写了一段提交后,竟然AC了,真是十一里的第一个惊喜呀。看来题目数据还是比较弱的,毕竟想数据的也不容易呀……入正题,每一个液面高度肯定对应一个球重心高度(这里的高度都相对球体底部),那么只要找一个球重心Y对于液面高度Z的函数Y(Z)就可以了。需要计算的中间量有G(Z):液体质量;H(Z):液体的重心。然后根据杆杠原理和已知的球壳重量算出Y(Z)。
        因为是密度是常数,所以求G(Z)只要从0到Z对面积积分后乘上密度就可以了。
        因为球是中心对称的,所以重心一定在球的中轴上,求出中轴上0~Z这一线段的重心即可(线段记为S)。S上某一点P的质量就是 包含P点且以S为法线的圆面的面积 乘上球密度。取S上任意一点Q,S上所有点对Q的力矩和等于重力对Q的力矩,以此求出重心位置。
       公式入下:(液体密度dest, 球质量mass, 球半径R)
       G(Z) = dest*(PI*R*Z*Z - PI*Z*Z*Z/3)
       H(Z) = Z*3/4 - R*Z/(12*R-4*Z);
       Y(Z) = (R*mass + H*G) / (G+mass)
 
       代码如下
 

// team520 1117 Accepted  0MS   180K  743Byte G++  2007-10-01 15:17:51.0 

#include <stdio.h>

double R, mass, dest;
double const PI = 3.141592653589793;

inline double G(double Z) {
     return dest* (PI*R*Z*Z - PI*Z*Z*Z/3);
}

inline double H(double Z) {
     return Z*3/4 - R*Z/(12*R-4*Z);
}

inline double Y(double Z) {
     double g = G(Z);
     return (R*mass + H(Z)*g)/(g+mass);
}

int main() {
     double guess;
     double best;
     double temp;
     while( scanf("%lf %lf %lf", &R, &mass, &dest) != EOF ) {
          if( mass == 0.0 ) {
               printf("0.00\n");
               continue;
          }
          best = R;
          for(guess=0.00; guess<=R; guess+=0.01) {
               temp = Y(guess);
               if( best > temp ) {
                    best = temp;
               }
          }
          printf("%.2lf\n", best);
     }
}

posted on 2010-10-26 12:55  曹某  阅读(245)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3