zoukankan      html  css  js  c++  java
  • usaco 3.4.1 fence4

    哇咔咔,终于过了我的第一道计算几何~~

    一开始看了题解,没看懂...然后在自己的思维下开始写:

    1,判断合法的闭合栅栏,其实就是判断线段两两是否相交(顶点相交不算相交)

    2,判断某条线段能否被看到,二分,先从出发点到该线段中点连一条线段(k,kk)(k为看的点,kk为线段中点),看其他线段(设为(p,q))与(k,kk)是否相交,若不相交,则说明线段(p,q)没有遮住该线段,若相交,则继续二分,直到到达精度限制

    3,这样写出来后,发现严重超时,开始考虑优化,如果从看的点出发到两个顶点所连线段都与其他某一条线段(设为(p,q))相交,那么线段(p,q)一定遮住该线段,这是可以肯定的。事实证明这是个很强大的优化,加上之后立刻AC。。。

    4,经验:对于一些很恶心的题,一开始也许思路比较模糊,但是要逼自己去写,写着写着,思维会慢慢打开...

    {
    ID:lucky141
    PROG:fence4
    LANG:PASCAL
    }
    program fence4;
    type
    node=record
    x,y:real;
    end;
    var
    a:array[1..201] of node;
    f:array[1..201] of boolean;
    n,i,j,ans:longint;
    flag:boolean;
    k:node;
    function max(p,q:real):real;
    begin
    if p>q then max:=p
    else max:=q;
    end;
    function min(p,q:real):real;
    begin
    if p<q then min:=p
    else min:=q;
    end;
    function chaji(p1,p2,p0:node):real;//计算叉积
    begin
    chaji:=(p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
    end;
    function check1(p1,q1,p2,q2:node):boolean;//端点相交不算相交
    begin
    check1:=(max(p1.x,q1.x)>=min(p2.x,q2.x)) and (max(p2.x,q2.x)>=min(p1.x,q1.x))
    and (max(p1.y,q1.y)>=min(p2.y,q2.y)) and (max(p2.y,q2.y)>=min(p1.y,q1.y))
    and (chaji(p2,q1,p1)*chaji(q1,q2,p1)>0)
    and (chaji(p1,q2,p2)*chaji(q2,q1,p2)>0);
    end;
    function check2(p1,q1,p2,q2:node):boolean;//端点相交算相交
    begin
    check2:=(max(p1.x,q1.x)>=min(p2.x,q2.x)) and (max(p2.x,q2.x)>=min(p1.x,q1.x))
    and (max(p1.y,q1.y)>=min(p2.y,q2.y)) and (max(p2.y,q2.y)>=min(p1.y,q1.y))
    and (chaji(p2,q1,p1)*chaji(q1,q2,p1)>=0)
    and (chaji(p1,q2,p2)*chaji(q2,q1,p2)>=0);
    end;


    以上全是计算几何的模板...



    function mid(p1,p2:node):node;//取中点
    var
    cc:node;
    begin
    cc.x:=(p1.x+p2.x)/2;
    cc.y:=(p1.y+p2.y)/2;
    mid:=cc;
    end;
    function endd(p,q:node):boolean;//判断精度
    begin
    if sqrt(sqr(p.x-q.x)+sqr(p.y-q.y))<0.01 then endd:=true
    else endd:=false;
    end;
    function work(l,r:node):boolean;//判断线段(l,r)能否被看到
    var
    kk:node;
    begin
    if endd(l,r) then exit(false);
    if check1(k,l,a[j],a[j+1]) and check1(k,r,a[j],a[j+1]) then exit(false);
    kk:=mid(l,r);
    for j:=1 to n do
    if i<>j then
    begin
    if check2(k,kk,a[j],a[j+1]) then
    begin
    if not work(l,kk) and not work(kk,r) then exit(false);
    end;
    end;
    exit(true);
    end;
    begin
    assign(input,'fence4.in');
    reset(input);
    assign(output,'fence4.out');
    rewrite(output);
    fillchar(a,sizeof(a),0);
    readln(n);
    readln(k.x,k.y);
    for i:=1 to n do
    readln(a[i].x,a[i].y);
    a[n+1]:=a[1];
    for i:=1 to n do
    for j:=1 to i-1 do
    if check1(a[i],a[i+1],a[j],a[j+1]) then
    begin
    writeln('NOFENCE');
    close(input);
    close(output);
    halt;
    end;
    ans:=0;
    fillchar(f,sizeof(f),false);
    for i:=1 to n do
    begin
    flag:=true;
    f[i]:=work(a[i],a[i+1]);
    if f[i] then inc(ans);
    end;
    writeln(ans);
    for i:=1 to n-2 do
    if f[i] then writeln(a[i].x:0:0,' ',a[i].y:0:0,' ',a[i+1].x:0:0,' ',a[i+1].y:0:0);
    if f[n] then writeln(a[n+1].x:0:0,' ',a[n+1].y:0:0,' ',a[n].x:0:0,' ',a[n].y:0:0);
    if f[n-1] then writeln(a[n-1].x:0:0,' ',a[n-1].y:0:0,' ',a[n].x:0:0,' ',a[n].y:0:0);
    close(input);
    close(output);
    end.

  • 相关阅读:
    【解压缩命令】 -费元星
    【虚拟机取得该虚拟机的所有权失败】--费元星
    solr 常见的问题整理 -费元星
    oracle 建立一个视图,然后授权其他用户访问
    虚拟机安装win7 64位-完美解决-费元星
    solr 学习
    CentOS安装JDK1.7
    Nginx+Tomcat多站点访问默认主页问题-狒狒完美解决-Q9715234
    pip 安装时提示uvloop/loop.c:20:10: fatal error: Python.h解决
    MySQL锁总结
  • 原文地址:https://www.cnblogs.com/stmq/p/3239262.html
Copyright © 2011-2022 走看看