Description
给予n个正方形,要求45°角放置,最左边的正方形紧贴Y轴,所有的正方形的下面的端点都在X轴上。然后按照正方形不能交错但要尽可能的挨着的原则,摆放,最后输出从上往下看能看到的正方形的编号
Input
多组用例,每组用例第一行为正方形个数n,第二行n个数表示每个正方形的边长,以n=0结束输入
Output
对于每组用例,输出最后从上往下看能看到的正方形编号
Sample Input
4
3 5 1 4
3
2 1 2
0
Sample Output
1 2 4
1 3
Solution
1、假如前i-1个正方形位置都确定了,那么可以让第i个正方形与前i-1个正方形每个都计算一次它如果和它相依靠的话左边坐标的值,然后取一个最大的便是这个正方形的左端点位置。
2、对于j < i的正方形,如果i的边长大于j那么j的最右能看到的部分就不会比i的最左端点大,反之,i的最左能看到的部分就不会比j最右端点小。
3、通过第2步筛选,将那些最左能看到的端点比最右能看到端点大或等于的去掉,剩下的就是所要求的。
Code
#include<cstdio>
#include<iostream>
using namespace std;
struct node
{
int len,l,r;
}sq[55];
int main()
{
int n;
while(scanf("%d",&n),n)
{
for(int i=1;i<=n;i++)
{
scanf("%d",&sq[i].len);
sq[i].l=0;//初始化左端点
for(int j=1;j<i;j++)
{
int temp;
if(sq[j].len>sq[i].len)
temp=sq[j].l+sq[j].len+sq[i].len;
else
temp=sq[j].l+3*sq[j].len-sq[i].len;
if(temp>sq[i].l)//更新左端点最大值
sq[i].l=temp;
}
sq[i].r=sq[i].l+2*sq[i].len;//右端点等于左端点加上边长二倍
}
for(int i=2;i<=n;i++)
for(int j=1;j<i;j++)
{
if(sq[j].len<sq[i].len&&sq[j].r>sq[i].l)//j遮住了i
sq[j].r=sq[i].l;
else if(sq[j].len>sq[i].len&&sq[j].r>sq[i].l)//i遮住了j
sq[i].l=sq[j].r;
}
for(int i=1;i<=n;i++)//最后左端点小于右端点的即为可以看到的正方体
if(sq[i].l<sq[i].r)
printf("%d ",i);
printf("\n");
}
return 0;
}