POJ 3347 Kadj Squares(复杂的线段相交问题)

题意:给予n个正方形,要求45°角放置,最左边的正方形紧贴Y轴,所有的正方形的下面的端点都在X轴上。然后按照正方形不能交错但要尽可能的挨着的原则,摆放,最后输出从上往下看能看到的正方形的编号。

思路:每新增一个正方形,就让它与左侧的每一个正方形贴紧,求其左端坐标,最终结果一定是最大的那个。然后求相应的最右端坐标。这样就转化为了线段,最后求出每条线段没有被覆盖的长度,如果长度大于0,即可输出,

看了一些别人的解题报告,扩大√2倍就能避免小数。

附上代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>

using namespace std;

struct square{
    int left;
    int right;
    int len;
}s[55];

int main()
{
    int n;
    while(cin >>n&&n){

        for(int i=0 ;i<n ;i++){

            cin>>s[i].len;
            s[i].left=0;
            for(int j=0 ;j<i ;j++){

                s[i].left=max(s[i].left,s[j].right-abs(s[i].len-s[j].len));
            }
            s[i].right=s[i].left+s[i].len*2;
        }

        for(int i=1 ;i<n ;i++){

            for(int j=0 ;j<i ;j++){

                if(s[i].left<s[i].right){

                    if(s[i].len>s[j].len && s[i].left<s[j].right)
                        s[j].right=s[i].left;
                    else if(s[i].len<s[j].len && s[i].left<s[j].right)
                        s[i].left=s[j].right;
                }
            }
        }
        bool mark=true;
        for(int i=0; i<n; i++)
            if(s[i].left<s[i].right){
                if(mark)
                    printf("%d", i+1), mark=false;
                else printf(" %d", i+1);
            }
        printf("
");
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

原文地址:https://www.cnblogs.com/wanglaoda/p/4937165.html