zoukankan      html  css  js  c++  java
  • 【HDU 1687】Lucky Light(思维+计算几何)

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1687

    题意:有一个光源,下面有很多放置的板子,问光线被板子分割之后在地上能产生多少块亮区(看题中的图就能看懂)。

    分析:这个题的做法和省选第一天的C题很像,由于是求在地面上,也就是一条直线上的亮区,我们可以求出地面上被木板遮挡形成的暗区的左坐标和右坐标,然后合并区间就可以了。而求地面上的坐标,可以用相似三角形,若光源为(sx,sy),点为(x1,y1)和(x2,y2),则地面上的坐标为:sx-(sx-s1)*sy/(sy-y1)和sx-(sx-s2)*sy/(sy-y2),需要注意的是两个坐标中较小的为左,大的为右,最好不要根据输入的x1,y1,x2,y2的大小关系去判定哪个为左哪个为右,这样很容易落下某种特殊情况,因为这个点wa了6次才ac。

    代码:

    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<math.h>
    #include<map>
    #include<algorithm>
    using namespace std;
    struct banzi{
        double startn;
        double endn;
    }A[500];
    bool comp(const banzi a ,const banzi b){
        return a.startn<b.startn;
    }
    int main(){
        int t;
        cin >> t;
        while(t--){
            int n;
            cin >> n;
            int sx,sy;
            cin >> sx >> sy;
            for(int i=0;i<n;++i){
                int x1,y1,x2,y2;
                cin >> x1 >> y1 >> x2 >> y2;
                double dian1=(double)sx-(sx-x1)*(sy)/(double)(sy-y1);
                double dian2=(double)sx-(sx-x2)*(sy)/(double)(sy-y2);
                A[i].startn=min(dian1,dian2);
                A[i].endn=max(dian1,dian2);
            }
            int light=(n>0?2:1);
            sort(A,A+n,comp);
            double endd=A[0].endn;
            for(int i=1;i<n;++i){
                if(A[i].startn<=endd){
                    endd=max(endd,A[i].endn);
                } else{
                    ++light;
                    endd=A[i].endn;
                }
            }
            cout << light << endl;
        }
    }
  • 相关阅读:
    简单的测试用例计划放法
    黑盒测试用例设计方法-等价类划分
    Redis净化板
    爬虫部署与Django
    怎样实现前端的优化
    关于Apache简介笔记
    yield生成器的经典案例
    石头剪刀布
    函数内是否可以修改传递进来的列表
    不定长参数的传递
  • 原文地址:https://www.cnblogs.com/Torrance/p/5445616.html
Copyright © 2011-2022 走看看