码迷,mamicode.com
首页 > 其他好文 > 详细

[2020杭电多校第三场]1008 Triangle Collision

时间:2020-07-29 17:46:49      阅读:81      评论:0      收藏:0      [点我收藏+]

标签:efi   opened   a*   fun   怎么   旋转   sig   scan   难点   

技术图片

 

 唯一难点应该在于怎么转点吧,直接看代码呗。

技术图片
//#pragma GCC optimize("-Ofast","-funroll-all-loops")
//#pragma GCC optimize(2)
//freopen("C://std/a.in","r",stdin);
//freopen("C://std/b.txt","w",stdout);
#include<bits/stdc++.h>
#define ll long long
#define PB push_back
#define endl ‘\n‘
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define ull unsigned long long
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define lowbit(x) (x & (-x))
#define rep(i, a, b) for(register int i = a ; i <= b ; ++ i)
#define per(i, a, b) for(register int i = b ; i >= a ; -- i)
#define clr(a, b) memset(a, b, sizeof(a))
#define in insert
#define random(x) (rand()%x)
#define PII(x, y) make_pair(x, y)
#define fi first
#define se second
#define pi acos(-1.0)
#define re register
//std::ios::sync_with_stdio(false);
using namespace std;
const double eps = 1e-6;
const int maxn = 500 + 50;
const ll mod = 1e9 + 7;
struct point{
    double x, y;
}v1,v2,v3;
struct line{
    double A, B, C;//Ax + By + C = 0;
}AB, BC, AC;
line PPL(point a, point b){// 两点确定直线的一般式
    if(a.x == b.x) return line{1, 0, a.x};
    if(a.y == b.y) return line{0, 1, a.y};
    return line{b.y-a.y, a.x-b.x, b.x*a.y - a.x*b.y};
}
double p_L_d(point a, line b){// 点到直线距离
    return 1.0*fabs(b.A*a.x+b.B*a.y+b.C) / sqrt(b.A*b.A+b.B*b.B);
}
point Rotate(point p, double rad){ //逆时针旋转
    return point{p.x*cos(rad)-p.y*sin(rad),p.x*sin(rad)+p.y*cos(rad)};
}
double L, vx, vy, x, y, k, h;
ll check(double t){
    ll ans = 0;
    point a = point{x, y};
    double dis = p_L_d(a, BC) + v1.y * t;
    if(dis < 0) ans += (ll)(-dis/h) + 1;
    else ans += (ll)(dis/h);
    v2 = Rotate(v1, 2*pi/3);
    dis = p_L_d(a, AC) + v2.y * t;
    if(dis < 0) ans += (ll)(-dis/h) + 1;
    else ans += (ll)(dis/h);
    v3 = Rotate(v1, -2*pi/3);
    dis = p_L_d(a, AB) + v3.y * t;
    if(dis < 0) ans += (ll)(-dis/h) + 1;
    else ans += (ll)(dis/h);
    return ans;
}
signed main(){ int T;

    cin >> T;
    while(T --){
        scanf("%lf %lf %lf %lf %lf %lf", &L, &x, &y, &vx, &vy, &k);
        h = 1.0 * L * sqrt(3) / 2;
        BC = PPL(point{L/2.0,0},point{-L/2.0,0});
        AB = PPL(point{L/2.0,0},point{0,h});
        AC = PPL(point{-L/2.0,0},point{0,h});
        v1 = point{vx, vy};
        double l = 0.0, r = 1e10;
        while(r - l >= eps){
            double mid = (l + r) / 2.0;
            //printf("%.8f %lld\n", mid, check(mid));
            if(check(mid) >= k) r = mid;
            else l = mid;
        }
        printf("%.8f\n", r);
    }
    return 0;
}
View Code

 

[2020杭电多校第三场]1008 Triangle Collision

标签:efi   opened   a*   fun   怎么   旋转   sig   scan   难点   

原文地址:https://www.cnblogs.com/Ketchum/p/13397968.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!