• HDU7049 Link with Grenade


    传送


    这题完全是一道数学题,前几步初等数学,后几步高等数学。


    对于3d空间,都能想到像橘子瓣儿一样取出一个薄片,算出那个不会被炸到的角度占([0,pi])的比例.记和(z)轴正向的夹角为(varphi),用初中物理知识可以得到

    [cos varphi leqslant frac{v_0^2t^2+25t^4-r^2}{10v_0t^3}(g=10已代入) (1) ]

    由此可见,(cosvarphi)是一个有理数,那么(varphi)也是一个有理数的概率很小,因此直接求角的方法似乎行不通。


    回到三维空间,我们根据角度画出单位球,那么被炸到的地方就是一个球冠,因此可以用球冠的表面积比上整个球的表面积(4pi R^2),就能求出被炸到的概率。

    那球冠的表面积怎么求?有公式,背住就更好。背不住可以用积分:一种是用元素法,但我元素法学的不太好,遂用第一类曲面积分(然而早忘了,现复习的),我们要求的,无非是

    [iintlimits_sum extrm{d}S ]

    其中( extrm{d}S=R^2sinvarphi extrm{d}varphi extrm{d} heta),那么

    [iintlimits_sum extrm{d}S=R^2 int_{0}^{varphi_0}sinvarphi extrm{d}varphiint_0^{2pi} extrm{d} heta ]

    这个当然好解,解出来是(2pi R^2(1-cosvarphi_0)),这样就能算出来不被炸到的概率:

    [P=1-frac{2pi R^2(1-cosvarphi_0)}{4pi R^2}=frac{1+cosvarphi_0}{2} ]

    由(1)可知,(cosvarphi_0)是个有理数,因此这样算出来的概率就是有理数。

    最后别忘了判断一定会被炸到和一定炸不到的情况,即分别让(1)式右侧(geqslant 1)(leqslant -1),得出两个不等式。而且因为题目给的(v_0,t,R)范围不大于(100),正好就可以在long long范围内进行比较大小。

    #include<bits/stdc++.h>
    using namespace std;
    #define enter puts("") 
    #define space putchar(' ')
    #define In inline
    typedef long long ll;
    typedef double db;
    const int INF = 0x3f3f3f3f;
    const ll mod = 1e9 + 7;
    In ll read()
    {
    	ll ans = 0;
    	char ch = getchar(), las = ' ';
    	while(!isdigit(ch)) las = ch, ch = getchar();
    	while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
    	if(las == '-') ans = -ans;
    	return ans;
    }
    In void write(ll x)
    {
    	if(x < 0) x = -x, putchar('-');
    	if(x >= 10) write(x / 10);
    	putchar(x % 10 + '0');
    }
    
    In ll quickpow(ll a, ll b)
    {
    	a %= mod;
    	ll ret = 1;
    	for(; b; b >>= 1, a = a * a % mod)
    		if(b & 1) ret = ret * a % mod;
    	return ret;
    }
    
    In ll solve(ll t, ll v, ll r)
    {
    	ll tp1 = v * v * t * t + 25LL * t * t * t * t - r * r;
    	ll tp2 = 10LL * v * t * t * t;
    	if(tp2 + tp1 <= 0) return 0;
    	if(tp1 - tp2 >= 0) return 1;
    	return ((tp1 % mod + mod) % mod * quickpow(tp2, mod - 2) % mod + 1) * quickpow(2, mod - 2) % mod;
    }
    
    int main()
    {
    	int T = read();
    	while(T--)
    	{
    		ll t = read(), v = read(), r = read();
    		write(solve(t, v, r)), enter;
    	}
    	return 0;
    }
    
  • 相关阅读:
    Git查询
    HDU-3038 How Many Answers Are Wrong 并查集
    CodeForcesEducationalRound40-D Fight Against Traffic 最短路
    HDU-6109 数据分割 并查集(维护根节点)
    ZOJ-3261 Connections in Galaxy War 并查集 离线操作
    AtCoderBeginner091-C 2D Plane 2N Points 模拟问题
    HDU-1878 欧拉回路 欧拉回路
    [笔记-图论]Floyd
    [笔记-图论]Bellman-Ford
    [笔记-图论]Dijkstra
  • 原文地址:https://www.cnblogs.com/mrclr/p/15127659.html
Copyright © 2020-2023  润新知