题意:从左到右给定n个正方形 的边长,而且正方形是贴在一起的求从上向下看,能看到的正方形编号,这个题需要注意的是扩大一下坐标乘以sqrt(2.0)转化为整点,避免精度问题,然后还有就是对于第i个正方形,必须要遍历一下0~i-1看它到底是和哪一个正方形相临的。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
const double eps=1e-10;
struct sq
{
double leftx,rightx;
double mindx;
double len;
int index;
};
sq q[100000];
bool cmp(sq a,sq b)
{
return a.len<b.len;
}
int n;
int ans[1000000];
int l=0;
int main()
{
while(~scanf("%d",&n) && n)
{
l=0;
for(int i=0;i<n;i++)
{
scanf("%lf",&q[i].len);
q[i].index=i;
// q[i].len*=*sqrt(2.0);
if(i==0)
{
q[i].leftx=0;
q[i].rightx=(2.0*q[i].len);
q[i].mindx=(q[i].len);
}
else
{
int a=-10000,b=-10000,c=-10000;
for(int j=0;j<i;j++)
{
if(q[i].len<q[j].len)
{
q[i].mindx=(q[j].mindx+sqrt(2.0*q[i].len*q[i].len*sqrt(2.0)*sqrt(2.0)));
q[i].leftx=(q[i].mindx-q[i].len);
q[i].rightx=(q[i].leftx+2.0*q[i].len);
}
else
{
q[i].mindx=(q[j].mindx+sqrt(2.0*q[j].len*q[j].len*sqrt(2.0)*sqrt(2.0)));
q[i].leftx=(q[i].mindx-q[i].len);
q[i].rightx=(q[i].leftx+2.0*q[i].len);
}
if(q[i].leftx>a)
{
a=q[i].leftx;
b=q[i].mindx;
c=q[i].rightx;
}
}
q[i].leftx=a;
q[i].mindx=b;
q[i].rightx=c;
}
//printf("%d %d %d\n",q[i].leftx,q[i].mindx,q[i].rightx);
}
sort(q,q+n,cmp);
for(int i=0;i<n-1;i++)
{
for(int j=i+1;j<n;j++)
{
if(q[i].leftx>=q[j].leftx && q[i].rightx<=q[j].rightx)
{
q[i].leftx=q[i].rightx=0;
break;
}
if(q[j].leftx>=q[i].leftx && q[j].leftx<=q[i].rightx)
q[i].rightx=q[j].leftx;
if(q[j].rightx<=q[i].rightx && q[j].rightx>=q[i].leftx)
q[i].leftx=q[j].rightx;
}
}
for(int i=0;i<n;i++)
{
if(q[i].rightx-q[i].leftx>0.0)
ans[l++]=q[i].index+1;
}
sort(ans,ans+l);
for(int i=0;i<l;i++)
printf("%d%c",ans[i],i==l-1?'\n':' ');
}
return 0;
}