如题,#1299726 在 Gym 上(开文操)会 WA on 1,在 QOJ 上能 AC。建议修改为如下 SPJ(对着原题 Java 版改的):
#include "testlib.h"
#include <algorithm>
#include <cmath>
#include <set>
#include <vector>
#define EPS 2e-3
#define MAX_C 1000000000
struct Edge
{
int v;
double l;
int len;
Edge(int v, double l, int len) : v(v), l(l), len(len) {}
bool operator<(Edge that) const
{
if (l != that.l)
return l < that.l;
return v < that.v;
}
};
int len;
double read(double w, int n, std::vector<double> x, std::vector<double> y, InStream &is, TResult type)
{
len = 0;
x[n] = is.readDouble();
y[n] = is.readDouble();
if (!is.seekEof())
quitf(type, "Extra data in output file");
if (x[n] < -EPS || w + EPS < x[n])
quitf(_wa, "x = %.3lf outside of the river", x[n]);
if (y[n] < -MAX_C || MAX_C + EPS < y[n])
quitf(_wa, "y = %.3lf outside of allowed range", y[n]);
std::set<Edge> edges;
for (int i = 0; i <= n; ++i)
edges.emplace(i, x[i] * x[i], 1);
double minD = w * w / 4.0;
double maxD = 0;
std::vector<bool> u(n + 1);
while (!edges.empty())
{
Edge e = *edges.begin();
edges.erase(edges.begin());
if (u[e.v])
{
continue;
}
if (e.l >= minD)
{
break;
}
maxD = std::max(maxD, e.l);
if (minD >= (w - x[e.v]) * (w - x[e.v]))
{
minD = (w - x[e.v]) * (w - x[e.v]);
len = e.len + 1;
}
minD = std::min(minD, (w - x[e.v]) * (w - x[e.v]));
if (minD <= maxD)
{
break;
}
u[e.v] = true;
for (int j = 0; j <= n; j++)
{
double d = (x[e.v] - x[j]) * (x[e.v] - x[j]) + (y[e.v] - y[j]) * (y[e.v] - y[j]);
if (!u[j])
{
edges.emplace(j, d, e.len + 1);
}
}
}
return std::sqrt(std::max(minD, maxD));
}
int main(int argc, char *argv[])
{
registerTestlibCmd(argc, argv);
double w = inf.readInt();
int n = inf.readInt();
std::vector<double> x(n + 1), y(n + 1);
for (int i = 0; i < n; ++i)
x[i] = inf.readInt(), y[i] = inf.readInt();
double ja = read(w, n, x, y, ans, _fail);
double pa = read(w, n, x, y, ouf, _pe);
if (std::abs(ja - pa) <= EPS)
{
quitf(_ok, "%.3lf, len = %d", ja, len);
}
TResult type = ja < pa ? _wa : _fail;
quitf(type, "Expected %.3lf, found %.3lf", ja, pa);
}