QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#647754 | #9434. Italian Cuisine | infCraft | WA | 1ms | 6780kb | C++14 | 10.0kb | 2024-10-17 15:34:09 | 2024-10-17 15:34:13 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define pb push_back
#define Yes cout << "Yes\n"
#define No cout << "No\n"
#define YES cout << "YES\n"
#define NO cout << "NO\n"
#define ff first
#define ss second
#define fori(x,y) for(int i=x;i<=(int)(y);++i)
#define forj(x,y) for(int j=x;j<=(int)(y);++j)
#define fork(x,y) for(int k=x;k<=(int)(y);++k)
#define debug(x) cerr << #x << " = " << x << endl
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
ll MOD = 998244353;
ll qpow(ll a,ll p) {ll res=1; while(p) {if (p&1) {res=res*a%MOD;} a=a*a%MOD; p>>=1;} return res;}
namespace Geometry {
const double PI = acos(-1);
const double eps = 1e-11;
int cmp(double x, double y) { // 比较两个浮点数的大小 x<y为-1,x>y为1
if (fabs(x-y)<eps) return 0;
else return x<y?-1:1;
}
int sgn(double x) { // 符号函数,大于0为1,小于0为-1
return cmp(x, 0);
}
struct Vector {
ll x, y;
Vector(): x(0), y(0) {}
Vector(ll x, ll y): x(x), y(y) {}
bool zero() const {
return sgn(x) == 0&&sgn(y) == 0;
}
ll distance2(const Vector& B) const {
return (x-B.x)*(x-B.x)+(y-B.y)*(y-B.y);
}
double distance(const Vector& B) const {
return sqrt(distance2(B));
}
double length2() const {
return x*x+y*y;
}
ll length() const {
return sqrt(length2());
}
Vector normalize() const {
return Vector(x/length(), y/length());
}
Vector operator+(const Vector& B) const {
return Vector(x+B.x, y+B.y);
}
Vector operator-(const Vector& B) const {
return Vector(x-B.x, y-B.y);
}
Vector operator*(ll k) const {
return Vector(x*k, y*k);
}
Vector operator/(ll k) const {
return Vector(x/k, y/k);
}
ll dot(const Vector& B) const {
return x*B.x+y*B.y;
}
ll operator*(const Vector& B) const {
return dot(B);
}
bool operator==(const Vector& B) const {
return sgn(x-B.x) == 0&&sgn(y-B.y) == 0;
}
ll cross(const Vector& B) const { // 从自身旋转到B的叉积(注意方向,逆时针正顺时针负)
return x*B.y-y*B.x;
}
// 从自身旋转到向量B的夹角(注意方向,逆时针正顺时针负)
// 180度算做PI而非-PI!!!
ll angle(const Vector& B) const {
ll co = acos(dot(B)/length()/B.length());
return sgn(co-PI) == 0? co: sgn(cross(B))*co;
}
bool parallel(const Vector& B) const { // 判断两个向量是否平行
return sgn(cross(B)) == 0;
}
};
struct Polygon { // 由向量构成的多边形
deque<Vector> points; // 尽量用逆时针排布
Polygon(): points(deque<Vector>()) {}
Polygon(deque<Vector> points): points(points) {}
/**
* 判断点是否在多边形内:
* 3:点在多边形顶点上
* 2:点在多边形的边上
* 1:点在多边形内部
* 0:点在多边形外部
*/
int isInPolygon(Vector point) const {
int n = points.size();
fori(0, n-1) {
if (point == points[i]) return 3;
}
fori(0, n-1) {
Vector v1 = points[i], v2 = points[(i+1)%n];
if ((point-v1).parallel(v2-v1)&&sgn((point-v1).dot(point-v2))<=0) return 2;
}
int num = 0;
fori(0, n-1) {
Vector v1 = points[i], v2 = points[(i+1)%n];
int c = sgn((point-v2).cross(v1-v2));
int u = sgn(v1.y-point.y);
int v = sgn(v2.y-point.y);
if (c>0&&u<0&&v>=0) num++;
if (c<0&&u>=0&&v<0) num--;
}
return num!=0;
}
/**
* 求多边形面积的两倍
* 但一定要注意!多边形得是逆时针排布!
*/
ll area2() const {
ll sum = 0;
int n = points.size();
fori(0, n-1) sum += points[i].cross(points[(i+1)%n]);
return sum;
}
double area() const { // 多边形面积
return area2()/2;
}
/**
* 求多边形的重心
*/
Vector gravityCenter() const {
Vector ans;
int n = points.size();
fori(0, n-1) {
Vector v1 = points[i], v2 = points[(i+1)%n];
ans = ans+(v1+v2)*v1.cross(v2);
}
ans = ans/area()/6;
return ans;
}
};
struct Line { // 直线
Vector p1, p2; // 两点确定一条直线
Line(Vector p1, Vector p2): p1(p1), p2(p2) {} // 基础构造方法
Line(Vector p, ll angle) { // 斜率构造方法:一点+斜率,0<=angle<=pi
p1 = p;
if (sgn(angle-PI/2) == 0) {p2 = (p1+Vector(0, 1));}
else {p2 = (p1+Vector(1, tan(angle)));}
}
Line(ll a, ll b, ll c) { // ax+by+c=0
if (sgn(a) == 0) {
p1 = Vector(0, -c/b);
p2 = Vector(1, -c/b);
}
else if (sgn(b) == 0) {
p1 = Vector(-c/a, 0);
p2 = Vector(-c/a, 1);
}
else {
p1 = Vector(0, -c/b);
p2 = Vector(1, -(c+a)/b);
}
}
// 判断一个点在直线上、左侧还是右侧
int pointLineRelation(Vector p) const {
ll c = (p-p1).cross(p2-p1);
if (c<0) return 1; // 1: 左侧
else if (c>0) return 2; // 2: 右侧
else return 0; // 0: 在直线上
}
// 计算点到直线的距离
double distanceToPoint(Vector p) const {
return fabs((p-p1).cross(p2-p1))/p1.distance(p2);
}
// 点在直线上的投影
Vector pointProj(Vector p) const {
ll k = (p-p1).dot(p2-p1)/p1.distance2(p2);
return p1+(p2-p1)*k;
}
// 与另一条直线的位置关系
int lineRelation(const Line& B) const {
if (sgn((p2-p1).cross(B.p2-B.p1)) == 0) {
if (pointLineRelation(B.p1) == 0) return 1; // 1: 重合
else return 0; // 0: 平行
}
return 2; // 2: 相交
}
// 与另一条直线的交点(注意!两条直线必须相交!!!)
Vector crossPoint(const Line& B) const {
ll s1 = (p2-p1).cross(B.p1-p1);
ll s2 = (p2-p1).cross(B.p2-p1);
return Vector(B.p1.x*s2-B.p2.x*s1, B.p1.y*s2-B.p2.y*s1)/(s2-s1);
}
};
struct Circle {
Vector c; // 圆心
ll r; // 半径
Circle(Vector c, ll r): c(c), r(r) {}
Circle(const Vector& a, const Vector& b, const Vector& c) { // 三点定圆
ll a1 = b.x-a.x, b1 = b.y-a.y, c1 = (a1*a1+b1*b1)/2;
ll a2 = c.x-a.x, b2 = c.y-a.y, c2 = (a2*a2+b2*b2)/2;
ll d = a1*b2-a2*b1;
Vector center(a.x+(c1*b2-c2*b1)/d, a.y+(a1*c2-a2*c1)/d);
this->c = center;
r = center.distance(a);
}
// 点和圆的位置关系
int pointCircleRelation(Vector p) const {
ll d = p.distance(c);
if (sgn(d-r)<0) return 0; // 0: 点在圆内
else if (sgn(d-r)==0) return 1; // 1: 点在圆上
else return 2; // 2: 点在圆外
}
// 直线和圆的位置关系
int lineCircleRelation(const Line& line) const {
ll d = line.distanceToPoint(c);
if (sgn(d-r)<0) return 0; // 0: 直线和圆相交
else if (sgn(d-r)==0) return 1; // 1: 直线和圆相切
else return 2; // 2: 直线在圆外
}
/**
* 求解直线和圆的交点
*
* @param line 直线
* @param p1 返回第一个交点
* @param p2 返回第二个交点
* @return 返回交点的个数
*/
int lineCrossCircle(const Line& line, Vector& p1, Vector& p2) const {
if (lineCircleRelation(line) == 2) return 0; // 没有交点
Vector pro = line.pointProj(c);
ll d = line.distanceToPoint(c);
ll k = sqrt(r*r-d*d);
if (sgn(k) == 0) {
p1 = pro, p2 = pro;
return 1; // 直线和圆相切,只有一个交点
}
Vector n = (line.p2-line.p1)/line.p2.distance(line.p1);
p1 = pro+n*k, p2 = pro-n*k;
return 2; // 两个交点
}
};
};
const int N = 2e5+7;
using namespace Geometry;
Vector pt[N];
ll area(Vector p1, Vector p2, Vector p3) {
return llabs((p3-p1).cross(p2-p1));
}
void solve() {
int n;
cin >> n;
ll x, y, r;
cin >> x >> y >> r;
Vector cen(x, y);
Circle cir(cen, r);
fori(1, n) cin >> pt[i].x >> pt[i].y;
fori(n+1, 2*n) pt[i] = pt[i-n];
ll ans = 0;
// 只算右半边
int l = 1;
ll tmp = 0; // 暂时的面积
fori(2, 2*n) {
while (Line(pt[l], pt[i]).pointLineRelation(cen) != 1) {
tmp -= area(pt[i-1], pt[l], pt[l+1]);
l++;
}
while (cir.lineCircleRelation(Line(pt[l], pt[i])) == 0) {
tmp -= area(pt[i-1], pt[l], pt[l+1]);
l++;
}
tmp += area(pt[i], pt[i-1], pt[l]);
ans = max(ans, tmp);
}
cout << ans << endl;
}
signed main() {
IOS;
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 6780kb
input:
3 5 1 1 1 0 0 1 0 5 0 3 3 0 5 6 2 4 1 2 0 4 0 6 3 4 6 2 6 0 3 4 3 3 1 3 0 6 3 3 6 0 3
output:
5 24 0
result:
ok 3 number(s): "5 24 0"
Test #2:
score: -100
Wrong Answer
time: 1ms
memory: 6640kb
input:
1 6 0 0 499999993 197878055 -535013568 696616963 -535013568 696616963 40162440 696616963 499999993 -499999993 499999993 -499999993 -535013568
output:
286862654137719264
result:
wrong answer 1st numbers differ - expected: '0', found: '286862654137719264'