您的位置:首页 > 编程语言 > Go语言

google code jam Star Wars(判断多元不等式是否有解)

2009-09-19 11:46 323 查看
题目只需要输出最小的power,不需要求解坐标。直接用二分查找,枚举所有坐标点看是否满足。

 

找到满足(|xi - x| + |yi - y| + |zi - z|) ≤ piY的最小的Y。

Ahyangyi的代码充分利用了该式的对称性

 x + y + z ≤ xi + yi + zi + piY
   x + y + z ≥ xi + yi + zi - piY
   x + y - z ≤ xi + yi - zi + piY
   x + y - z ≥ xi + yi - zi - piY
   x - y + z ≤ xi - yi + zi + piY
   x - y + z ≥ xi - yi + zi - piY
   -x + y + z ≤ -xi + yi + zi + piY
   -x + y + z ≥ -xi + yi + zi - piY


A ≤ x + y + z ≤ B
   C ≤ x + y - z ≤ D
   E ≤ x - y + z ≤ F
   G ≤ -x + y + z ≤ H
则答案是是满足A<B&&C<D&&E<F&&G<H的最小的Y。

#include <stdio.h>

int n;
int x[1000], y[1000], z[1000], p[1000];

int test (double pow) {
double best[2][2][2];
int a, b, c;

for (a = 0; a < 2; a ++)
for (b = 0; b < 2; b ++)
for (c = 0; c < 2; c ++)
best[a][b][c] = 1e20;

for (int i = 0; i < n; i ++)
for (a = 0; a < 2; a ++)
for (b = 0; b < 2; b ++)
for (c = 0; c < 2; c ++)
best[a][b][c] <?= (a?x[i]:-x[i]) + (b?y[i]:-y[i]) + (c?z[i]:-z[i]) + pow*p[i];

for (a = 0; a < 2; a ++)
for (b = 0; b < 2; b ++)
for (c = 0; c < 2; c ++)
if (best[a][b][c] + best[!a][!b][!c] < 0)
return 0;
return 1;
}

int main () {
int t, i, ct = 0;

for (scanf("%d", &t); t > 0; t --) {
scanf("%d", &n);

for (i = 0; i < n; i ++)
scanf("%d%d%d%d", x + i, y + i, z + i, p + i);

double l, m, r;

l = 0;
r = 1e20;
for (int ii = 0; ii < 100; ii ++) {
m = (l + r) / 2;

if (test(m))
r = m;
else
l = m;
}

printf("Case #%d: %.6lf/n", ++ ct, (l + r) / 2);
}

return 0;
}


ACRush的代码则比较规矩,通过不断移动cruiser的位置来逼近最佳点,通用性更强。

 

 

const int maxn=1000+5;

int n;
double X[maxn],Y[maxn],Z[maxn],P[maxn];

double solve(double X0,double Y0,double Z0)
{
double result=0;
for (int i=0;i<n;i++)
{
double d=fabs(X0-X[i])+fabs(Y0-Y[i])+fabs(Z0-Z[i]);
checkmax(result,d/P[i]);
}
return result;
}
int main()
{
//	freopen("..//input.txt","r",stdin);
//	freopen("..//C-small-attempt0.in","r",stdin);freopen("..//C-small-attempt0.out","w",stdout);
freopen("..//C-large.in","r",stdin);freopen("..//C-large.out","w",stdout);
int testcase;
scanf("%d",&testcase);
for (int caseId=1;caseId<=testcase;caseId++)
{
printf("Case #%d: ",caseId);
scanf("%d",&n);
for (int i=0;i<n;i++) scanf("%lf%lf%lf%lf",&X[i],&Y[i],&Z[i],&P[i]);
double X0=0,Y0=0,Z0=0;
double L=1e6;
double R0=solve(X0,Y0,Z0);
for (int step=0;step<1000;step++)
{
double tmp;
tmp=solve(X0-L,Y0,Z0);if (tmp<R0) R0=tmp,X0-=L;
tmp=solve(X0+L,Y0,Z0);if (tmp<R0) R0=tmp,X0+=L;
tmp=solve(X0,Y0-L,Z0);if (tmp<R0) R0=tmp,Y0-=L;
tmp=solve(X0,Y0+L,Z0);if (tmp<R0) R0=tmp,Y0+=L;
tmp=solve(X0,Y0,Z0-L);if (tmp<R0) R0=tmp,Z0-=L;
tmp=solve(X0,Y0,Z0+L);if (tmp<R0) R0=tmp,Z0+=L;
if ((step+1)%6==0) L/=1.618;
}
printf("%0.12lf/n",R0);
}
}


 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  google c ini