• [解方程]Map 2022杭电多校第6场 1009


    Problem Description

    Sakuyalove has a large world map MM and a small world map mm. Both of the them are in the shape of rectangle. The small map mm is compressed from the large map MM. If the length of MM is aa and the width of MM is bb, then the length of mm is kaka and the width of mm is kbkb, where 0 < k < 10exactly one point PP represents the same place in small map and large map (For example, in the following pictures, the location of the pin on both maps represents Tokyo, Japan). Sakuyalove wants to find out this point PP. Please help her.

    Input

    The first line contains one integer T(1\le T\le 10^5)T(1≤T≤105), described the number of test cases.

    Each test case contains eight lines. Each line has two integers x, y (-10^{3}\leq x, y\leq 10 ^ 3)x,y(−103≤x,y≤103) separated by one space.

    The first four lines are the coordinates of the upper left corner, the upper right corner, the lower right corner and the lower left corner of MM.

    The last four lines are the coordinates of the upper left corner, the upper right corner, the lower right corner and the lower left corner of mm.

    It is guaranteed that mm is within MM, both of the them are in the shape of rectangle, and mm is compressed from MM.

    Please note that the upper left corner, the upper right corner, the lower right corner and the lower left corner of mm and MM are one-to-one corresponding. For example, in the picture of Hint below, the correspondence of points is A-aA−a, B-bB−b, C-cC−c, D-dD−d. But A-cA−c, B-dB−d, C-aC−a, D-bD−b is not allowed.

    Output

    Your output should contains TT lines. Each line contains two real numbers x, yx,y separated by one space, represents the coordinates of the point PP. Your absolute error should not exceed 10 ^ {-6}10−6.

    Sample Input

    1

    0 5

    15 5

    15 0

    0 0

    3 2

    9 5

    10 3

    4 0

    Sample Output

    6.000000 2.000000

    Hint

    In the first example, the picture is like this:

    题意: 每组数据给出八个点,分别是一个大矩形四顶点和一个小矩形四顶点,保证小矩形一定在大矩形内部,求出点P满足P点在小矩形中的相对位置和大矩形中的相对位置相同。

    分析: 设向量OP = 向量OA + lambda*向量AB + mu*向量AD,那么还应该有向量OP = 向量Oa + lambda*向量ab + mu*向量ad,二者联立消去OP得:

    根据x坐标和y坐标方程解出该lambda和mu就可以求出P点坐标了,不过这题要注意精度,前期运算可以用整数进行,到了不得已的时候再转成浮点运算。 

    具体代码如下:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #define double long double
    9. using namespace std;
    10. const double eps = 1e-8;
    11. const double inf = 1e20;
    12. const double pi = acos(-1.0);
    13. const int maxp = 1010;
    14. //`Compares a double to zero`
    15. int sgn(double x)
    16. {
    17. if(fabs(x) < eps)return 0;
    18. if(x < 0)return -1;
    19. else return 1;
    20. }
    21. //square of a double
    22. inline double sqr(double x){return x*x;}
    23. struct Point
    24. {
    25. int x, y;
    26. Point(){}
    27. Point(int _x,int _y){x = _x, y = _y;}
    28. void input(){scanf("%d%d",&x,&y);}
    29. void output(){printf("%.2f %.2f\n",x,y);}
    30. bool operator == (Point b)const{return sgn(x-b.x) == 0 && sgn(y-b.y) == 0;}
    31. //第一关键字为x,第二关键字为y
    32. bool operator < (Point b)const{return sgn(x-b.x)== 0?sgn(y-b.y)<0:x
    33. Point operator -(const Point &b)const{return Point(x-b.x,y-b.y);}
    34. //叉积
    35. double operator ^(const Point &b)const{return x*b.y - y*b.x;}
    36. //点积
    37. double operator *(const Point &b)const{return x*b.x + y*b.y;}
    38. //返回长度
    39. double len(){return hypot(x,y);/*库函数*/}
    40. //返回长度的平方
    41. double len2(){return x*x + y*y;}
    42. //返回两点的距离
    43. double distance(Point p){return hypot(x-p.x,y-p.y);}
    44. Point operator +(const Point &b)const{return Point(x+b.x,y+b.y);}
    45. Point operator *(const double &k)const{return Point(x*k,y*k);}
    46. Point operator /(const double &k)const{return Point(x/k,y/k);}
    47. //`计算pa 和 pb 的夹角`
    48. //`就是求这个点看a,b 所成的夹角`
    49. //`测试 LightOJ1203`
    50. double rad(Point a,Point b)
    51. {
    52. Point p = *this;
    53. return fabs(atan2( fabs((a-p)^(b-p)),(a-p)*(b-p) ));
    54. }
    55. //`化为长度为r的向量`
    56. Point trunc(double r)
    57. {
    58. double l = len();
    59. if(!sgn(l))return *this;
    60. r /= l;
    61. return Point(x*r,y*r);
    62. }
    63. //`逆时针旋转90度`
    64. Point rotleft(){return Point(-y,x);}
    65. //`顺时针旋转90度`
    66. Point rotright(){return Point(y,-x);}
    67. //`绕着p点逆时针旋转angle`
    68. Point rotate(Point p,double angle)
    69. {
    70. Point v = (*this) - p;
    71. double c = cos(angle), s = sin(angle);
    72. return Point(p.x + v.x*c - v.y*s,p.y + v.x*s + v.y*c);
    73. }
    74. };
    75. Point p1[4], p2[4];
    76. signed main(){
    77. int T;
    78. cin >> T;
    79. while(T--){
    80. for(int i = 0; i < 4; i++)
    81. p1[i].input();
    82. for(int i = 0; i < 4; i++)
    83. p2[i].input();
    84. Point AB = p1[1]-p1[0];
    85. Point ab = p2[1]-p2[0];
    86. Point AD = p1[3]-p1[0];
    87. Point ad = p2[3]-p2[0];
    88. Point OA = p1[0];
    89. Point Oa = p2[0];
    90. //x坐标方程各系数
    91. int a1 = (AB-ab).x;
    92. int b1 = (AD-ad).x;
    93. int c1 = (Oa-OA).x;
    94. //y坐标方程各系数
    95. int a2 = (AB-ab).y;
    96. int b2 = (AD-ad).y;
    97. int c2 = (Oa-OA).y;
    98. double mu = 1.0*(1ll*c1*a2-1ll*a1*c2)/(1ll*b1*a2-1ll*a1*b2);
    99. double lambda = 1.0*(c1-1ll*b1*mu)/a1;
    100. double x = Oa.x+ab.x*lambda+ad.x*mu;
    101. double y = Oa.y+ab.y*lambda+ad.y*mu;
    102. cout << fixed << setprecision(10) << x << " " << y << endl;
    103. }
    104. return 0;
    105. }

  • 相关阅读:
    arm架构docker安装mysql5.7
    Synchronized锁的升级
    【数据结构与算法】顺序表&手撕vector
    商品购物管理与推荐系统Python+Django网页界面+协同过滤推荐算法
    22牛客多校6 - Z-Game on grid(博弈,反推)
    Android实战——使用状态模式重构下载状态及行为
    【系统设计】邻近服务
    Linux系统编程系列之进程间通信-消息队列
    【C语言】进阶——程序编译
    XXL-JOB 分布式任务调度中心搭建
  • 原文地址:https://blog.csdn.net/m0_55982600/article/details/126177988