1. 程式人生 > 實用技巧 >[2020杭電多校第三場]1008 Triangle Collision

[2020杭電多校第三場]1008 Triangle Collision

唯一難點應該在於怎麼轉點吧,直接看程式碼唄。

//#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