平行x 轴的线段 是否 遮掩 计算几何的扩大数据运算的典型应用,扩大根号2倍之后就避免了小数。 poj 3347 Kadj Squares

题目来源: http://poj.org/problem?id=3347

题意:变长不同的n个正方形,斜45度按顺序平放在坐标轴上,尽量靠左但不能跃出x=0,问从上往下看,哪些正方形是可见的。

题解:1、假如前i-1个正方形位置都确定了,那么可以让第i个正方形与前i-1个正方形每个都计算一次它如果和它相依靠的话左边顶点坐标的值,然后取一个最大的便是这个正方形的左端点位置。  这个结论 需要仔细推敲。

   2、对于j<i的正方形,如果i的边长大于j那么j的最右能看到的部分就不会比i的最左端点大,反之,i的最左能看到的部分就不会比j最右端点小。

   3、通过第2步筛选,将那些最左能看到的端点比最右能看到端点大或等于的去掉,剩下的就是所要求的。

4: 注意 ,我们 存放 正方形 端点的坐标时,  是将坐标轴 扩大 √2 倍。

代码如下:

  

#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <vector>
#include <set>
#include <math.h>
#include <cmath>
#include <map>
#include <queue>

using namespace std;
typedef long long ll;
const int N =60;
struct Line
{
    int left;
    int right;
    int length;
};
int n;
Line line[N];
int side[N];
void solve()
{

}
int main()
{
    while(cin>>n && n)
    {
        cin>>side[0];
        line[0].left=0;
        line[0].right=2*side[0];  // 坐标轴 扩大 √2 倍
        line[0].length=2*side[0];
        for (int i=1;i<n ;i++)
        {
            cin>> side[i];
            int left=0;
            for(int j=i-1 ;j>=0; j--)
                left=max(left, line[j].right-abs(side[i]-side[j]) );    // 第i 个 正方形的左端点的 x位置 是 与 前 i-1 个正方形依靠的 最大 x 值
            line[i].left=left;
            line[i].right=line[i].left+2*side[i];
            line[i].length=2*side[i];
        }
        for(int i=1 ;i<n;i++)
        {
            for(int j=0; j<i;j++)
            {
                if(line[i].length < line[j].length && line[i].left < line[j].right)  // 更新左右端点的值
                    line[i].left=line[j].right;
                if(line[i].length > line[j]. length && line[i].left < line[j].right )
                    line[j].right=line[i].left;
            }
        }
        int count=0;
        for(int i=0 ;i<n ;i++)
        {
            if(line[i].left < line[i].right)   
            {
                if(count)
                    printf(" ");
                printf("%d",i+1);
                count=1;
            }
        }
        printf("
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zn505119020/p/3628332.html