运行如下代码。输入:
1
91 688 931 120 135 366 879 688
输出最后有:
...
y in [120.0000000000, 688.0000000000]
compare 91.0000000000 & 91.0000000000
fuck 1
...
Fuck 1 代表比较的第一个值小于第二个值,Why?
#include <iostream>
#include <math.h>
#include <map>
#include <vector>
#include <algorithm>
#include <stdio.h>
#include <iomanip>
using namespace std;
#define int long long
const int N = 1e5 + 5, INF = 1e18;
struct Point {
long double x, y;
};
Point make(long double x, long double y) {
Point T; T.x = x, T.y = y;
return T;
}
Point read() {
long double x, y; cin>>x>>y;
return make(x, y);
}
struct Line {
long double k, b, xmn, xmx, ymn, ymx, x; bool h;
};
// long double abs(long double b) {
// if(b < 0) return -b;
// else return b;
// }
Line line(Point A, Point B) {
// y = kx + b
// A.y = k * A.x + b 1.
// B.y = k * B.x + b 2.
// 1. - 2. ---> A.y - B.y = k * (A.x - B.x)
Line r;
r.k = (A.y - B.y) / (A.x - B.x);
if(A.x == B.x) r.x = A.x, r.h = 1;
else r.h = 0;
r.b = ((A.y - r.k * A.x) + (B.y - r.k * B.x)) / 2;
r.xmn = min(A.x, B.x);
r.xmx = max(A.x, B.x);
r.ymn = min(A.y, B.y);
r.ymx = max(A.y, B.y);
return r;
}
long double get(Line L, long double x) {
return L.k * x + L.b;
}
bool in(Line L, Point P) {
cout<<fixed<<setprecision(10)<<"compare "<<P.x<<" & "<<L.xmn<<endl;
if(P.x < L.xmn) cout<<"fuck 1"<<endl;
if(P.x > L.xmx) cout<<"fuck 2"<<endl;
if(P.y < L.ymn) cout<<"fuck 3"<<endl;
if(P.y > L.ymx) cout<<"fuck 4"<<endl;
if(P.x >= L.xmn && P.x <= L.xmx && P.y >= L.ymn && P.y <= L.ymx) return 1;
else return 0;
}
Point common(Line A, Line B) {
// y = k1x + b1
// y = k2x + b2
// (k1 - k2) * x + (b1 - b2) = 0
// x = (b2 - b1) / (k1 - k2)
Point P;
P.x = (B.b - A.b) / (A.k - B.k);
P.y = (get(A, P.x) + get(B, P.x)) / 2;
// cout<<"P = ("<<P.x<<", "<<P.y<<")"<<endl;
// cout<<A.h<<" & "<<B.h<<endl;
if(A.h && B.h) return make(INF, INF);
if(A.h) {
P = make(A.x, B.k * A.x + B.b);
if(in(A, P) && in(B, P)) return P;
else return make(INF, INF);
}
if(B.h) {
P = make(B.x, A.k * B.x + A.b);
if(in(A, P) && in(B, P)) return P;
else return make(INF, INF);
}
if(in(A, P) && in(B, P)) return P;
else return make(INF, INF);
}
long double cal(Line L, long double y) {
if(L.h) return L.x;
// y = kx + b
// x = (y - b) / k
long double r = (y - L.b) / L.k;
// cout<<"("<<y<<" - "<<L.b<<") / "<<L.k<<" = "<<r<<endl;
return r;
}
long double area(Point A, Point B, Point C) {
double r = 0.5 * fabs(A.x * B.y + B.x * C.y + C.x * A.y - A.x * C.y - B.x * A.y - C.x * B.y);
// cout<<r<<endl;
return r;
}
long double solve() {
Point A = read(), B = read(), C = read(), D = read();
if(A.y == B.y || C.y == D.y) {
cout<<"type 1"<<endl;
return 0;
}
if(A.y < B.y) swap(A, B);
if(C.y < D.y) swap(C, D);
Line X = line(A, B), Y = line(C, D); // cout<<X.h<<" "<<Y.h<<endl;
// cout<<X.k<<" & "<<Y.k<<endl;
if(X.k > 0 && Y.k > 0) {
if(A.x == C.x) {
if(X.k >= Y.k) {
cout<<"type 0"<<endl;
return 0;
}
}
if(A.x > C.x) {
if(A.y >= C.y) {
if(X.k >= Y.k) {
cout<<"type 2"<<endl;
return 0;
}
else;
} else {
if(X.k >= Y.k);
else;
}
} else {
if(A.y >= C.y) {
if(X.k >= Y.k);
else;
} else {
if(X.k >= Y.k);
else {
cout<<"type 3"<<endl;
return 0;
}
}
}
}
if(X.k < 0 && Y.k < 0) {
if(A.x >= C.x) {
if(A.y >= C.y) {
if(X.k >= Y.k);
else;
} else {
if(X.k >= Y.k) {
cout<<"type 4"<<endl;
return 0;
}
else;
}
} else {
if(A.y >= C.y) {
if(X.k >= Y.k);
else {
cout<<"type 5"<<endl;
return 0;
}
} else {
if(X.k >= Y.k);
else;
}
}
}
// cout<<"X: y = "<<X.k<<"x + "<<X.b<<endl;
// cout<<"Y: y = "<<Y.k<<"x + "<<Y.b<<endl;
Point P = common(X, Y);
// cout<<"P = ("<<P.x<<", "<<P.y<<")"<<endl;
if(P.x == INF) {
cout<<"type 6"<<endl;
return 0;
}
if(A.y >= C.y) {
// C 投影到 AB
Point Q = make(cal(X, C.y), C.y);
cout<<"C = ("<<C.x<<", "<<C.y<<")"<<endl;
cout<<"Q = ("<<Q.x<<", "<<Q.y<<")"<<endl;
cout<<"x in ["<<X.xmn<<", "<<X.xmx<<"]"<<endl;
cout<<"y in ["<<X.ymn<<", "<<X.ymx<<"]"<<endl;
if(in(X, Q)) return area(C, Q, P);
else {
cout<<"type 7"<<endl;
return 0;
}
} else {
// A 投影到 CD
Point Q = make(cal(Y, A.y), A.y);
if(in(Y, Q)) return area(A, Q, P);
else {
cout<<"type 8"<<endl;
return 0;
}
}
}
signed main() {
int T; cin>>T;
while(T--) {
// cout<<"T = "<<T<<endl;
long double ans = solve(); cout<<fixed<<setprecision(2)<<ans<<endl;
// printf("%.2lf\n", solve());
}
}