题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=7049
思想:变换坐标系 几何
虑转换参考系,给人和手雷都加上一个反向的重力加速度,则手雷做匀速直线运动,人做匀加速直线运动。t秒后,人的位置是固定的,而手雷的位置是一个圆,手雷可以炸到人的范围也是一个圆(如图1)。作出如图2所示的三角形,可以用余弦定理求得手雷可以炸到人的仰角 。
图1.png
图2.png
根据球冠表面积公式,可以炸到人的部分的表面积为
以上出自官方题解。
上面算的是会炸到的情况 不会炸到就是用 1 去减一下就好了
代码:
#include <bits/stdc++.h>
#define pb push_back
#define xx first
#define yy second
#define in(x) scanf("%d",&x)
#define lin(x) scanf("%lld",&x)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int N = 2e6+10;
const int M = N*2;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
const double eps = 1e-7;
const double PI = acos(-1);
ll qpow(ll a,ll b){ll res = 1;while(b){if(b&1) res = res*a%MOD;a = a*a%MOD;b >>= 1;}return res;}
int n,m,k;
int A[N];
char str[N];
ll inv(ll x){
return qpow(x,MOD-2);
}
signed main(){
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
#endif
int T; in(T);
int t,v,r;
const int g = 10;
while(T--){
in(t),in(v),in(r);
ll a = (ll)g*t*t/2,b = (ll)v*t;
if(a + b <= r) puts("0"); // v方向和重力方向相同
else if(abs(a - b) >= r) puts("1"); // v方向和重力方向相反
else{
// cos = (a^2+b^2-r^2)/2ab
// 1 - ((1-cos)/2) = ((a+b)^2 - r^2 ) / 4ab
ll tp = ((a + b) * (a + b) - r * r) * inv(4*a*b%MOD) % MOD;
printf("%lld\n",tp);
}
}
return 0;
}