poj3347线段相交,扩大数据运算

链接:http://poj.org/problem?id=3347

题意:一系列正方形立着排列,正方形互不重叠,能贴着放就贴着,求俯视的时候能看到哪些正方形。

思路:把正方形的重叠问题转化为线段相交问题。正方形投影到x轴上就是横着的那条对角线,如果把正方形边长扩大根号2倍的话,对角线长就是整数,便于处理。然后再来对线段长进行裁剪,如果某部分被遮住了的话,就去掉这部分。还有个重要的地方是求正方形的左边顶点的横坐标,对于某个正方形,假定他和前面的正方形都是贴着的,求出相应的横坐标,取最大,即可。

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;

struct squ
{
    int l,r,len;
}a[52];

int main()
{
    int n;
    while((cin>>n) && n)
    {
        for(int i=1;i<=n;i++)
        {
            cin>>a[i].len;
            a[i].l=0;
            for(int j=1;j<i;j++)//sqrt(2)
                a[i].l=max(a[i].l,a[j].r-abs(a[i].len-a[j].len));
            a[i].r=a[i].l+a[i].len*2;
            for(int j=1;j<i;j++)
            {
                if(a[j].len<a[i].len && a[j].r>a[i].l)
                   a[j].r=a[i].l;
                else if(a[j].len>a[i].len && a[j].r>a[i].l)
                   a[i].l=a[j].r;
            }
        }
        int k=1;
        for(int i=1;i<=n;i++)
        {
            if(a[i].l<a[i].r)
            {
                if(k)
                {
                    cout<<i;k=0;
                }
                else cout<<' '<<i;
            }
        }
        cout<<endl;
    }
    return 0;
}

完全没想到投影成线段,然后判断线段相交。

究竟是我抛弃了历史,还是历史遗弃了我。
原文地址:https://www.cnblogs.com/54zyq/p/3189805.html