题意:给你几个正方形的边长,正方一个顶点在x轴上然后边与x轴的夹角为45度,每个正方形都是紧贴的,问从上面看能看的正方形的编号
思路:正方形有左右两个顶点,怎么判断被覆盖呢?
便利每一条线段,如果和其他线段有交集那个去掉交集部分,继续遍历,最后看是否还剩下线段,剩下说明没有被覆盖,反之被覆盖了
怎么确定每个正方形的区间呢,根据边长,将边长扩大根号2倍就避免了小数,如果两个边长相等的正方形放在一起,两个线段一定在同一水平线上,如果边长一大一小,那一定是大的在上面,而且多出的部分正是他们的边长之差。这就好办了,先算出最左边的坐标加上长度就是左右边的坐标了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
struct Point
{
int left,right,len;
};
Point p[100];
int Max(int a,int b)
{
return a > b ? a : b;
}
int main()
{
int n;
while(scanf("%d",&n) != EOF)
{
int num = 0;
int ans[100] = {0};
if(n == 0) break;
for(int i = 0; i < n; i++)
{
scanf("%d",&p[i].len);
}
for(int i = 0; i < n; i++)
{
p[i].left = 0;
for(int j = 0; j < i; j++)
{
p[i].left = Max(p[i].left,p[j].right - abs(p[i].len-p[j].len));
}
p[i].right = p[i].left + 2*p[i].len;
}
for(int i = 0; i < n; i++)
{
int left = p[i].left,right = p[i].right;
for(int j = 0; j < n; j++)
{
if(i!= j && p[i].len <= p[j].len && p[j].left <= right && p[j].right >= left )
{
if(p[j].left <= left && p[j].right >= right || left >= right)
{
ans[i] = 1;break;
}
else if(p[j].right <= right && p[j].right >= left )
{
left = p[j].right;
}
else if(p[j].left <= right && p[j].left >= left)
{
right = p[j].left;
}
}
}
}
int i;
for(i = 0; i < n; i++)
{
if(!ans[i])
{
printf("%d",i+1);break;
}
}
for(int j = i+1; j < n; j++)
{
if(!ans[j])
{
printf(" %d",j+1);
}
}
printf("\n");
}
return 0;
}