POJ_3347
首先我们要确定每个正方形安放的位置,只要枚举前面已经放好的正方形并计算当前正方形安放的位置,最后再取这些位置中最右边的位置即可。
接着我们要计算每个正方形上方能否被其他正方形覆盖。显然,如果某一个正方形的边长比当前的正方形边长更小,是不可能覆盖到当前的正方形的。除此之外,我们可以先计算一下当前正方形左边的正方形能覆盖到的最右边的位置,以及右边的正方形能覆盖到的最左边的位置,依据这两个值便很好判定当前正方形是否被完全覆盖掉了。
#include<stdio.h>
#include<string.h>
#include<math.h>
#define MAXD 60
#define INF 0x3f3f3f3f
#define zero 1e-8
int N, ans[MAXD];
double x[MAXD], a[MAXD], y[MAXD];
int dcmp(double x)
{
if(fabs(x) < zero)
return 0;
if(x < 0)
return -1;
return 1;
}
void init()
{
int i, j, k;
double left, t;
for(i = 1; i <= N; i ++)
{
scanf("%lf", &a[i]);
y[i] = a[i] / sqrt(2.0);
}
x[0] = y[0];
for(j = 2; j <= N; j ++)
{
left = -INF;
for(i = 1; i < j; i ++)
{
if(y[i] >= y[j])
{
t = x[i] + 2 * y[j];
if(t > left)
left = t;
}
else
{
t = x[i] + 2 * y[i];
if(t > left)
left = t;
}
}
x[j] = left;
}
}
void solve()
{
int i, j, k = 0;
double left, right, t;
for(i = 1; i <= N; i ++)
{
left = -INF, right = INF;
for(j = 1; j < i; j ++)
if(y[j] > y[i])
{
t = x[j] + y[j];
if(t > left)
left = t;
}
for(j = i + 1; j <= N; j ++)
if(y[j] > y[i])
{
t = x[j] - y[j];
if(t < right)
right = t;
}
if(dcmp(left - x[i] - y[i]) < 0 && dcmp(x[i] - y[i] - right) < 0 && dcmp(left - right) < 0)
ans[k ++] = i;
}
printf("%d", ans[0]);
for(i = 1; i < k; i ++)
printf(" %d", ans[i]);
printf("\n");
}
int main()
{
for(;;)
{
scanf("%d", &N);
if(!N)
break;
init();
solve();
}
return 0;
}