1 条题解

  • 0
    @ 2025-8-24 22:00:30

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Hiraeth
    **

    搬运于2025-08-24 22:00:30,当前版本为作者最后更新于2018-09-16 14:32:36,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    我是真的菜啊

    真的好难啊

    想了好久好久

    大体思路就是:

    因为对折次数是有上限的,所以这个值也不会太大,

    那么最后提供答案的数据点的结果应该也不会太大,

    如果不放心的话,可以开一个unsigned long long

    所以就对输入的每个点,把一张折叠了的纸再沿着折痕返回过去,

    相当于在一个平面直角坐标系中寻找一个已知点的对称点

    数学的手动滑稽

    边读边扫,在输入过程中排除中途不符合情况的点,

    最后看在初始的图形上有多少的点剩下来,既符合情况的点

    要求点关于直线的对称点。

    对称点的一种求法是斜率之积为-1

    然后求解

    这是我打的智障做法……

    据大佬讲解可以用旋转向量公式

    x1=x0cosB-y0sinB

    y1=x0sinB+y0cosB

    Orz一波大佬

    美丽的折纸 溜了溜了

    #include<bits/stdc++.h>
    
    using namespace std ; 
    
    const int MAXN = 10 ; 
    const int MAXM = 60 ; 
    const double eps = 1e-6 ; 
    int N , M ;
    
    struct Point {
        double x , y ; 
        Point ( const double x , const double y ) :
        x ( x ) , y ( y ) {} ;
    } ; 
    
    struct Vector {
        double x , y ; 
        Vector ( const double x , const double y ) : 
        x ( x ) , y ( y ) {} ; 
    } ; 
    
    struct Line {
        Point From , To ; 
        Line ( const double x1 , const double y1 , 
               const double x2 , const double y2 ) :
        From ( x1 , y1 ) , To ( x2 , y2 ) {} ;
        Vector toVector () const ;
    } ;
    
    Vector operator - ( const Point & First , const Point & Second ) {
        return Vector ( First . x - Second . x , First . y - Second . y ) ; 
    } 
    
    Point operator - ( const Point & First , const Vector & Second ) {
        return Point ( First . x - Second . x , First . y - Second . y ) ; 
    } 
    
    Vector operator * ( const double k , const Vector & Input ) {
        return Vector ( k * Input . x , k * Input . y ) ; 
    }
    
    Point operator + ( const Point & First , const Vector & Second ) {
        return Point ( First . x + Second . x , First . y + Second . y ) ; 
    }
    
    
    double operator ^ ( const Vector & First , const Vector & Second ) {
        return First . x * Second . y - First . y * Second . x ; 
    }  
    
    double operator * ( const Vector & First , const Vector & Second ) {
        return First . x * Second . x + First . y * Second . y ; 
    }
    
    double abs ( const Vector & Input ) {
        return sqrt ( Input . x * Input . x + Input . y * Input . y ) ; 
    }
    
    Vector Line :: toVector () const { return To - From ; }  
    
    vector < Line > Opts ; 
    
    Point reflect ( const Point o , const Line L ) {
        const double dis = ( ( L . From - o ) ^ ( L . To - o ) ) / abs ( L . toVector () ) ; 
        const Vector Lp = 1.0 / abs ( L . toVector () ) * L . toVector () ; 
        return o + 2.0 * dis * Vector ( Lp . y , - Lp . x ) ;
    }
    
    int Query ( const Point o , const int T ) {
        if ( T == -1 ) 
            return ( eps <= o . x && o . x <= 100.0 - eps ) && 
                   ( eps <= o . y && o . y <= 100.0 - eps ) ; 
        const double CrossValue =   ( ( Opts [ T ] . From - o ) ^ ( Opts [ T ] . To - o ) ) ;
        if ( CrossValue < - eps ) return 0 ;     
        if ( - eps <= CrossValue && CrossValue <= eps ) return 0 ; 
        return Query ( o , T - 1 ) + 
               Query ( reflect ( o , Opts [ T ] ) , T - 1 ) ; 
    }
    
    int main () {
        scanf ( "%d" , & N ) ; 
        for ( int i = 0 ; i < N ; ++ i ) {
            double x1 , y1 , x2 , y2 ; 
            scanf ( "%lf%lf%lf%lf" , & x1 , & y1 , & x2 , & y2 ) ; 
            Opts . push_back ( Line ( x1 , y1 , x2 , y2 ) ) ; 
        } 
        scanf ( "%d" , & M ) ; 
        while ( M -- ) {
            double x , y ; 
            scanf ( "%lf%lf" , & x , & y ) ; 
            printf ( "%d\n" , Query ( Point ( x , y ) , N - 1 ) ) ;
        }
        return 0 ;
    }
    
    • 1

    信息

    ID
    3435
    时间
    2000ms
    内存
    125MiB
    难度
    7
    标签
    递交数
    0
    已通过
    0
    上传者