HDU - 6812 Kindergarten Physics(分块/规律)

题目链接


这题第一眼看上去想积分,然后队友翻开大物课本疯狂学习,看了半个小时也没有好的思绪,然后另外一名队友说分块能写,就尝试了而且成功了

比赛时想的是,因为距离公式为 s = v t + 0.5 a t 2 s=vt+0.5at^2 ,然后 t < 0.001 t<0.001 应该可以忽略的,那么就按固定时间 d e l t = 0.001 delt=0.001 计算 1000 t 1000*t 次,这样就能得到答案了!

可是实际上仔细考虑 G G 以及距离范围,发现在精度范围内无论如何都不会移动的,那么直接输出距离就好了…orz

#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define ins insert
#define Vector Point
#define lowbit(x) (x&(-x))
#define mkp(x,y) make_pair(x,y)
#define mem(a,x) memset(a,x,sizeof a);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<double,double> pdd;
const double eps=1e-8;
const double pi=acos(-1.0);
const int inf=0x3f3f3f3f;
const double dinf=1e300;
const ll INF=1e18;
const int Mod=1e9+7;
const int maxn=2e5+10;
const double G=6.6743e-11;
const double delt=0.001;

int main(){
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    //ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T,m1,m2,R,tt;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d%d%d",&m1,&m2,&R,&tt);
        int v1=0,v2=0;
        double r=R;
        int tot=tt*1000;
        for(int i=1;i<=tot;i++){
            double a1=G*m2/(r*r),a2=G*m1/(r*r);
            double s1=v1*delt+0.5*a1*delt*delt,s2=v2*delt+0.5*a2*delt*delt;
            v1=v1+a1*delt,v2=v2+a2*delt;
            r=r-(s1+s2);
        }
        printf("%.6f\n",r);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_44691917/article/details/107740556