把每个正方形抽象成三个数据,最左端点和最右端点的横坐标L,R,以及两个端点的高度H
也就是一条线段,和它的位置,判断遮挡的时候只需要判断这些线段就可以了
难点就是确定每个线段的位置,每次新加一个正方形时,算出与前面所有的正方形相接的左端点值
最大的那个就是真实位置,计算公式 L=S[i].R-abs(S[i].H-H); S[i]为前面的正方形
确定位置后按照高度从高到低排序,然后用标记判断是否能被看到
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=50+10;
struct square
{
int id,h;
int l,r;
bool operator < (const square &u) const
{
return h>u.h;
}
}a[N];
bool vis[N*100];
int ans[N],cnt;
int main()
{
int n;
while(~scanf("%d",&n)&&n)
{
for(int i=0;i<n;i++)
{
scanf("%d",&a[i].h);
a[i].id=i+1;
int ml=0;
for(int j=0;j<i;j++)
ml=max(ml,a[j].r-abs(a[i].h-a[j].h));
a[i].l=ml;a[i].r=ml+2*a[i].h;
}
sort(a,a+n);
memset(vis,false,sizeof(vis));
cnt=0;
for(int i=0;i<n;i++)
{
bool flag=false;
for(int j=a[i].l+1;j<=a[i].r;j++)
{
if(!vis[j]) flag=true;
vis[j]=true;
}
if(flag) ans[cnt++]=a[i].id;
}
sort(ans,ans+cnt);
printf("%d",ans[0]);
for(int i=1;i<cnt;i++)
printf(" %d",ans[i]);
printf("\n");
}
return 0;
}