QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#352877#4234. Tic Tac Toe CountingPetroTarnavskyi#WA 0ms3848kbC++204.2kb2024-03-13 17:36:522024-03-13 17:36:54

Judging History

This is the latest submission verdict.

  • [2024-03-13 17:36:54]
  • Judged
  • Verdict: WA
  • Time: 0ms
  • Memory: 3848kb
  • [2024-03-13 17:36:52]
  • Submitted

answer

#include <bits/stdc++.h>

using namespace std;

#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define RFOR(i, a, b) for(int i = (a) - 1; i >= (b); i--)
#define SZ(a) int(a.size())
#define ALL(a) a.begin(), a.end()
#define PB push_back
#define MP make_pair
#define F first
#define S second

typedef long long LL;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef long double db;

const db EPS = 1e-9;

struct Pt
{
	db x, y;
	Pt operator-(const Pt& p) const
	{
		return {x - p.x, y - p.y};
	}
	Pt operator*(db d) const
	{
		return {x * d, y * d};
	}
	Pt operator/(db d) const
	{
		return {x / d, y / d};
	}
};

db sq(const Pt& p)
{
	return p.x * p.x + p.y * p.y;
}

db abs(const Pt& p)
{
	return sqrt(sq(p));
}

int sgn(db x)
{
	return (EPS < x) - (x < -EPS);
}

Pt perp(const Pt& p)
{
	return {-p.y, p.x};
}

db dot(const Pt& p, const Pt& q)
{
	return p.x * q.x + p.y * q.y;
}

db cross(const Pt& p, const Pt& q)
{
	return p.x * q.y - p.y * q.x;
}

db orient(const Pt& p, const Pt& q, const Pt& r)
{
	return cross(q - p, r - p);
}

bool half(const Pt& p)
{
	assert(sgn(p.x) != 0 || sgn(p.y) != 0);
	return sgn(p.y) == -1 ||
		(sgn(p.y) == 0 && sgn(p.x) == -1);
}

void polarSortAround(const Pt& o, vector<pair<Pt, int>>& v)
{
	sort(ALL(v), [o](auto pp, auto qq)
	{
		Pt p = pp.F - p;
		Pt q = qq.F - o;
		bool hp = half(p), hq = half(q);
		if (hp != hq)
			return hp < hq;
		int s = sgn(cross(p, q));
		if (s != 0)
			return s == 1;
		return sq(p) < sq(q);
	});
}

struct Line
{
	Pt n;
	db c;
	Line (const Pt& p, const Pt& q): n(perp(q - p)), c(-dot(n, p)) {}
	db side(const Pt& p) const
	{
		return dot(n, p) + c;
	}
};

bool parallel(const Line& l1, const Line& l2)
{
	return sgn(cross(l1.n, l2.n)) == 0;
}

Pt inter(const Line& l1, const Line& l2)
{
	db d = cross(l1.n, l2.n);
	assert(sgn(d) != 0);
	return perp(l2.n * l1.c - l1.n * l2.c) / d;
}

db areaPolygon(const vector<Pt>& v)
{
	db area = 0.0;
	int n = SZ(v);
	FOR(i, 0, n)
		area += cross(v[i], v[(i + 1) % n]);
	return abs(area) / 2.0;
}

db C;

vector<Pt> hplaneInter(vector<Line> lines)
{
	lines.PB({{-C, C}, {-C, -C}});
	lines.PB({{-C, -C}, {C, -C}});
	lines.PB({{C, -C}, {C, C}});
	lines.PB({{C, C}, {-C, C}});
	sort(ALL(lines), []
		(const Line& l1, const Line& l2)
	{
		bool h1 = half(l1.n), h2 = half(l2.n);
		if (h1 != h2)
			return h1 < h2;
		int p = sgn(cross(l1.n, l2.n));
		if (p != 0)
			return p > 0;
		return sgn(l1.c / abs(l1.n)
			- l2.c / abs(l2.n)) < 0;
	});
	lines.erase(unique(ALL(lines), parallel),
		lines.end());
	deque<pair<Line, Pt>> d;
	for (const Line& l : lines)
	{
		while (SZ(d) > 1 && sgn(l.side(
			(d.end() - 1)->S)) < 0)
			d.pop_back();
		while (SZ(d) > 1 && sgn(l.side(
			(d.begin() + 1)->S)) < 0)
			d.pop_front();
		if (!d.empty() && sgn(cross(
			d.back().F.n, l.n)) <= 0)
			return {};
		if (SZ(d) < 2 || sgn(d.front().F.side(
			inter(l, d.back().F))) >= 0)
		{
			Pt p;
			if (!d.empty())
			{
				p = inter(l, d.back().F);
				if (!parallel(l, d.front().F))
					d.front().S = inter(l, d.front().F);
			}
			d.PB({l, p});
		}
	}
	vector<Pt> res;
	for (auto [l, p] : d)
	{
		if (res.empty()
			|| sgn(sq(p - res.back())) > 0)
			res.PB(p);
	}
	return res;
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout << fixed << setprecision(15);
	int n, m;
	cin >> n >> m;
	vector<Pt> v(m);
	for (Pt& p : v)
		cin >> p.x >> p.y;
	C = n;
	db ans = 0;
	FOR(i, 0, m)
	{
		Pt p = v[i];
		vector<pair<Pt, int>> cur;
		cur.reserve(m + 3);
		FOR(j, 0, m)
		{
			if (j != i)
				cur.PB({v[j], 1});
		}
		for (int x : {0, n})
			for (int y : {0, n})
				cur.PB({{(db)x, (db)y}, 0});
		polarSortAround(p, cur);
		int sz = SZ(cur);
		assert(sz == m + 3);
		int ptr = 0, cnt = 0;
		FOR(k, 0, SZ(cur))
		{
			Pt q = cur[k].F;
			while (ptr < k || (ptr < SZ(cur) + k && sgn(orient(p, q, cur[ptr % sz].F)) >= 0))
			{
				cnt += cur[ptr % sz].S;
				ptr++;
			}
			db area = areaPolygon(hplaneInter({{p, q}}));
			ans = max(ans, (db)cnt / m - area / (n * n));
			cnt -= cur[k].S;
		}
	}
	cout << ans << "\n";
	return 0;
}

詳細信息

Test #1:

score: 0
Wrong Answer
time: 0ms
memory: 3848kb

input:

4
XX..O....
X...OX...
OOOX.X.X.
OOOXXX...

output:

0.000000000000000

result:

wrong answer 1st lines differ - expected: '191 194', found: '0.000000000000000'