| ||
|
生成一个全排列,最后检测,不用剪枝也能过。
一个油滴扩展时,半径是和其他圆相切,和四边相切时求出的半径中最小的一个。
一开始错了,因为没有单独讨论油滴在另一个油滴扩展的圆内的情况,这种情况就不能扩展,不单独讨论会变成负面积。。。
#include <cstdio>
#include <cmath>
#include <string>
long x[100000];
long y[100000];
long que[100000];
double r[100000];
bool used[100000];
long top = 0;
long X1,X2,Y1,Y2;
long n;
const double pi = 3.1415926535897932384626433832795;
const double eps = 1e-8;
double ans = 0;
using namespace std;
inline double MIN(double a,double b)
{
return a<b?a:b;
}
inline double MAX(double a,double b)
{
return a>b?a:b;
}
double DIST(long a,long b)
{
return sqrt(double((x[b]-x[a])*(x[b]-x[a])+(y[b]-y[a])*(y[b]-y[a])));
}
long getint()
{
long rs=0;char tmp;bool sgn=1;
do tmp = getchar();
while (!isdigit(tmp)&&tmp-'-');
if (tmp=='-'){sgn=0;tmp=getchar();}
do rs=(rs<<3)+(rs<<1)+tmp-'0';
while (isdigit(tmp=getchar()));
return sgn?rs:-rs;
}
void dfs(long l,double sum)
{
if (l == n+1)
{
ans = MAX(sum,ans);
return;
}
for (long i=1;i<n+1;i++)
{
if (!used[i])
{
used[i] = true;
double min = 1e19;
for (long j=1;j<top+1;j++)
{
double dd = DIST(que[j],i);
if (dd > r[j]+eps)
min = MIN(DIST(que[j],i)-r[j],min);
else
min = 0;
}
min = MIN(abs(x[i]-X1),min);
min = MIN(abs(X2-x[i]),min);
min = MIN(abs(y[i]-Y1),min);
min = MIN(abs(Y2-y[i]),min);
que[++top] = i;
r[top] = min;
dfs(l+1,sum + pi*min*min);
used[i] = false;
top--;
}
}
}
int main()
{
freopen("oil.in","r",stdin);
freopen("oil.out","w",stdout);
n = getint();
X1 = getint();
Y1 = getint();
X2 = getint();
Y2 = getint();
for (long i=1;i<n+1;i++)
{
x[i] = getint();
y[i] = getint();
}
dfs(1,0);
printf("%.0lf",abs(X2-X1)*abs(Y2-Y1)-ans);
return 0;
}