Fruit Slicer
切水果几何题,精度感觉特别坑,转化为long long 来做。具体代码如下。需要思考思考啊。
#include <bits/stdc++.h>
#define rep(i , a , b) for(int i=(a);i<=(b);i++)
using namespace std;
typedef long long ll;
struct Point {
ll x , y;
Point () {}
Point (double _x , double _y) {
x = _x;
y = _y;
}
Point operator- (const Point &b) const {
return Point (x - b.x , y - b.y);
}
ll operator^ (const Point &b) const {
return x * b.y - y * b.x;
}
ll operator* (const Point &b) const {
return x * b.x + y * b.y;
}
};
struct Circle {
Point c;
ll r;
Circle () {}
Circle (Point c , ll r) : c (c) , r (r) {}
bool operator< (const Circle &a) const {
if ( a.c.x != c.x ) return c.x < a.c.x;
return c.y < a.c.y;
}
} e[111];
ll dist (Point p1 , ll a , ll b , ll c) {
ll x = p1.x;
ll y = p1.y;
if ( abs (x * a + y * b + c) >= 1e9 ) return - 1;
return ( x * a + y * b + c ) * ( x * a + y * b + c );
}
bool inter (ll a , ll b , ll c , Circle c1) {
if ( dist (c1.c , a , b , c) == - 1 ) return false;
return dist (c1.c , a , b , c) <= 1ll * 40000 * ( a * a + b * b );
}
bool same (Circle a , Circle b) {
if ( a.c.x == b.c.x && a.c.y == b.c.y ) return true;
return false;
}
ll read (string s) {
ll op;
ll ans = 0;
if ( s[ 0 ] == '-' ) op = - 1;
else op = 1;
for ( int i = 0 ; i < s.length () ; i ++ ) {
if ( s[ i ] == '.' || s[ i ] == '-' ) continue;
ans = ans * 10 + s[ i ] - '0';
}
return ans * op;
}
int main () {
int n;
scanf ("%d" , &n);
for ( int i = 1 ; i <= n ; i ++ ) {
string s1 , s2;
cin >> s1 >> s2;
e[ i ].c.x = read (s1);
e[ i ].c.y = read (s2);
e[ i ].r = 1ll * 100;
}
if ( n == 1 ) {
printf ("1\n");
return 0;
}
if ( n == 2 ) {
printf ("2\n");
return 0;
}
int ans = 0;
sort (e + 1 , e + 1 + n);
rep (i , 1 , n) {
int res = 0;
rep (j , 1 , n) {
if ( same (e[ i ] , e[ j ])) res ++;
}
ans = max (ans , res);
}
int ma = 0;
rep (i , 1 , n) {
rep(j , i + 1 , n) {
if ( same (e[ i ] , e[ j ])) continue;
ll x1 = e[ i ].c.x , y1 = e[ i ].c.y;
ll x2 = e[ j ].c.x , y2 = e[ j ].c.y;
ll a = y2 - y1;
ll b = x1 - x2;
ll c = x2 * y1 - x1 * y2;
Point v = e[ j ].c - e[ i ].c;
int ans1 = 2;
int ans2 = 2;
rep (k , 1 , n) {
if ( k == i || k == j ) continue;
Point v1 = e[ k ].c - e[ i ].c;
if ( inter (a , b , c , e[ k ]) && ( v ^ v1 ) <= 0 ) ans1 ++;
if ( inter (a , b , c , e[ k ]) && ( v ^ v1 ) >= 0 ) ans2 ++;
}
ma = max (ma , max (ans1 , ans2));
}
}
ans = max (ma , ans);
cout << ans << endl;
return 0;
}