链接:https://cn.vjudge.net/problem/POJ-3347
题意:给出n个正方形,把正方形按顺序放进第一象限中并且正方形的两底边与x轴成45度角。尽可能让正方形紧挨着放。问俯视时,最后哪几个正方形不会被完全遮挡。
思路:如果所有边长都扩大倍,那么正方形的对角线也就是2倍的边长,这样就避免了精度问题。然后,每次放正方形(i)时,都遍历一遍前面放好的正方形(j)。计算i与j正好相切时,i的最左边的顶点的横坐标(即结构体力里的l),最后取一个最大值。根据对角线的长度,算出i的最右边的顶点的横坐标(即结构体力里的r)。问题转化为求没有被完全覆盖的线段,对于本题,我们分别向前向后遍历,把i被覆盖的部分去掉,即改变i的l和r值,最后判断l是否小于r即可。具体看图,手残,自己画画就懂了。
#include <cstdio>
#include <algorithm>
#include <cmath>
#define ll long long
using namespace std;
const int N = 100;
struct node
{
int l,r,s;
}ls[N];
int n,ans[N],cnt;
int main(void)
{
while(~scanf("%d",&n)&&n)
{
cnt=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&ls[i].s);
ls[i].l=0;
for(int j=1;j<i;j++)
ls[i].l=max(ls[i].l,ls[j].r-abs(ls[i].s-ls[j].s));
ls[i].r=ls[i].l+ls[i].s*2;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<i;j++)
if(ls[i].s<ls[j].s&&ls[i].l<ls[j].r)
ls[i].l=ls[j].r;
for(int j=i+1;j<=n;j++)
if(ls[i].s<ls[j].s&&ls[j].l<ls[i].r)
ls[i].r=ls[j].l;
}
for(int i=1;i<=n;i++)
if(ls[i].l<ls[i].r)
ans[++cnt]=i;
for(int i=1;i<=cnt;i++)
printf("%d%c",ans[i]," \n"[i==cnt]);
}
return 0;
}