POJ 3347 && HDU 2417 Kadj Squares(计算几何)

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;
}

你可能感兴趣的:(POJ 3347 && HDU 2417 Kadj Squares(计算几何))