1 条题解

  • 0
    @ 2025-5-14 22:00:14

    题意分析

    1. 游戏规则

      • 玩家 AA 的初始位置为 (0,0)(0, 0)
      • 每次移动后,根据提示更新物体可能存在的区域:
        • "更热":物体位于新位置比旧位置更近的区域(即到新位置的距离 << 到旧位置的距离)。
        • "更冷":物体位于新位置比旧位置更远的区域(即到新位置的距离 >> 到旧位置的距离)。
        • "相同":物体位于到新旧位置距离相等的区域(即垂直平分线)。
    2. 几何约束

      • 每次提示将物体限制在某个半平面或直线范围内。
      • 所有约束的交集即为物体可能存在的区域。
    3. 输出要求

      • 计算当前所有约束的交集面积,保留 22 位小数。

    解题思路

    不妨设上一个点为p,现在走到的点为c,显然到p的距离和到c的距离相等的点就在线段pc的中垂线上,而这条直线把平面分成了两个半平面,如果是Hotter就说明object在更靠近c的这个半平面内,如果是Colder就说明object在更靠近p的这个半平面,于是,我们就把这个问题转化成半平面交的问题了。

    C++ 代码实现

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<set>
    #include<map>
    #include<cstring>
    #include<vector>
    #include<string>
    #define LL long long
    using namespace std;
    class Point
    {
    public:
          double x,y;
          Point(){}
          Point( double xx , double yy ):x(xx),y(yy){}
    }p[124],q[124];
    void Init( Point &pre )
    {
        pre = Point( 0 , 0 );
        p[1] = Point( 0 , 0 );
        p[2] = Point( 0 , 10 );
        p[3] = Point( 10 , 10 );
        p[4] = Point( 10 , 0 );
        p[5] = p[1];
        p[0] = p[4];
    }
    void Get_line( Point pre, Point cur , double &A, double &B, double &C)
    {
        Point a = Point( (pre.x + cur.x)/2.0 , ( pre.y + cur.y )/2.0 );
        A = cur.x - pre.x;
        B = cur.y - pre.y;
        C = -A*a.x - B*a.y;    
    }
    Point Get_point( Point a,Point b, double A,double B,double C )
    {
         double u = fabs( A*a.x + B*a.y + C );
        double v = fabs( A*b.x + B*b.y + C );
        Point ans;
        ans.x = ( u*b.x + v*a.x )/(u+v);
        ans.y = ( u*b.y + v*a.y )/(u+v);
        return ans;    
    }
    int Solve( int n ,double A,double B,double C)
    {
        int m = 0;
           for( int i = 1 ; i <= n ; i ++ )
           {
           if( A*p[i].x + B*p[i].y + C > 0 )
               q[++m] = p[i];
           else
           {
               if( A*p[i-1].x + B*p[i-1].y + C > 0 )
                   q[++m] = Get_point( p[i] , p[i-1] ,A,B,C );
               if(A*p[i+1].x + B*p[i+1].y + C > 0)
                      q[++m] = Get_point( p[i] , p[i+1] ,A,B,C );         
           }        
        }
        for( int i =1 ; i <= m; i ++ )
             p[i] = q[i];
        p[m+1] = p[1];
        p[0] = p[m];
        return m;
    }
    double Area( int n )
    {
          double area=0;
          p[n+1] = p[1];
          for( int i = 1; i <= n ; i ++ )
               area += p[i].x*p[i+1].y - p[i].y*p[i+1].x;
          return fabs( area/2.0 );    
    }
    int main(  )
    {
        Point pre,cur;
        bool flag = false;
        char str[12];
        double  A,B,C;
        int n = 4;
        Init( pre );
          while( scanf( "%lf%lf%s",&cur.x,&cur.y,str )==3 )
          {
             if( !flag )
             {
                 Get_line( pre , cur , A,B,C );
                 if( str[0] == 'C' ) 
                 {
                     if( A*pre.x + B*pre.y + C < 0 )
                     {
                         A = -A; B = -B ; C = -C; 
                     }             
                 }
                 else if( str[0] == 'H' )
                      {
                          if( A*cur.x + B*cur.y + C < 0 )
                          {
                             A = -A ; B = -B ; C = -C;        
                          }
                      }
                  else {flag = true;puts( "0.00" );continue;}
                    n =  Solve( n ,A ,B ,C );    
                 printf("%.2f\n",Area( n ) );
                 pre = cur;    
             }
             else puts( "0.00" );          
        }
        //system( "pause" );
        return 0;
    }
    
    • 1

    信息

    ID
    1541
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者