标签:style blog http io ar color os sp for
题意: n个正方形,边长为S[i],斜45度按顺序平放在坐标轴上,尽量靠左,但是不能与前面任何一个相交,问从上往下看,哪些正方形是可见的。
解法: 我们先将边长扩张成sqrt(2)倍边长,这样的话就可以直接进行整数运算了。
然后分两步:
1.求出所有的b[i]
2.再进行区间覆盖判定
第一步:我们知道前面所有b[j]后,b[i]就是满足与前面任何一个都不相交的一个最左的位置。要满足于前面的都不相交又最靠左,我们就有: b[i] = max(b[i],b[j]+2*min(S[i],S[j])), 根据下图,推一下就能得出。
第二步: 将所有正方形的L,R已经求出,然后n^2地更新每个正方形的L,R为可见的L,R :
1.如果S[i] > S[j] (j=1~i-1),并且 seg[i].L < seg[j].R , 那么 seg[j].R = seg[i].L
2.如果S[i] < S[j] .. , 并且 seg[i].L < seg[j].R , 那么 seg[i].L = seg[j].R
--------------------------------------------------------------------------------------------------
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
//data segment
int S[55],b[55];
struct Seg{
int L,R,LEN;
}seg[55];
//data ends
int main()
{
int n,i,j;
double gen2 = sqrt(2.0);
while(scanf("%d",&n)!=EOF && n)
{
for(i=1;i<=n;i++)
scanf("%d",&S[i]);
b[1] = S[1];
for(i=2;i<=n;i++)
{
b[i] = b[i-1];
for(j=i-1;j>=1;j--)
b[i] = max(b[i],b[j] + 2*min(S[i],S[j]));
}
for(i=1;i<=n;i++)
{
seg[i].L = b[i] - S[i];
seg[i].R = b[i] + S[i];
seg[i].LEN = S[i];
}
for(i=1;i<=n;i++)
{
for(j=1;j<i;j++)
{
if(seg[i].LEN > seg[j].LEN && seg[i].L < seg[j].R)
seg[j].R = seg[i].L;
if(seg[i].LEN < seg[j].LEN && seg[i].L < seg[j].R)
seg[i].L = seg[j].R;
}
}
int fir = 1;
for(i=1;i<=n;i++)
{
if(seg[i].L < seg[i].R)
{
if(fir) cout<<i, fir = 0;
else cout<<" "<<i;
}
}
puts("");
}
return 0;
}
POJ 3347 Kadj Squares --扩展长度,几何,线段覆盖
标签:style blog http io ar color os sp for
原文地址:http://www.cnblogs.com/whatbeg/p/4161258.html