Educational Codeforces Round 112 (Rated for Div. 2)-B. Two Tables-题解

111 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

@TOC

Educational Codeforces Round 112 (Rated for Div. 2)-B. Two Tables

传送门 Time Limit: 2 seconds Memory Limit: 256 megabytes

Problem Description

You have an axis-aligned rectangle room with width WW and height HH, so the lower left corner is in point (0,0)(0, 0) and the upper right corner is in (W,H)(W, H).

There is a rectangular table standing in this room. The sides of the table are parallel to the walls, the lower left corner is in (x1,y1)(x_1, y_1), and the upper right corner in (x2,y2)(x_2, y_2).

You want to place another rectangular table in this room with width ww and height hh with the width of the table parallel to the width of the room.

例图

The problem is that sometimes there is not enough space to place the second table without intersecting with the first one (there are no problems with tables touching, though).

You can't rotate any of the tables, but you can move the first table inside the room.

What is the minimum distance you should move the first table to free enough space for the second one?

Input

The first line contains the single integer tt (1t50001 \le t \le 5000) — the number of the test cases.

The first line of each test case contains two integers WW and HH (1W,H1081 \le W, H \le 10^8) — the width and the height of the room.

The second line contains four integers x1x_1, y1y_1, x2x_2 and y2y_2 (0x1<x2W0 \le x_1 < x_2 \le W; 0y1<y2H0 \le y_1 < y_2 \le H) — the coordinates of the corners of the first table.

The third line contains two integers ww and hh (1wW1 \le w \le W; 1hH1 \le h \le H) — the width and the height of the second table.

Output

For each test case, print the minimum distance you should move the first table, or 1-1 if there is no way to free enough space for the second table.

Your answer will be considered correct if its absolute or relative error doesn't exceed 10610^{-6}.

Sample Input

5
8 5
2 1 7 4
4 2
5 4
2 2 5 4
3 3
1 8
0 3 1 6
1 5
8 1
3 0 6 1
5 1
8 10
4 5 7 8
8 5

Sample Onput

1.000000000
-1
2.000000000
2.000000000
0.000000000

Note

The configuration of the first test case is shown in the picture. But the movement of the first table is not optimal. One of the optimal movement, for example, is to move the table by (0,1)(0, -1), so the lower left corner will move from (2,1)(2, 1) to (2,0)(2, 0). Then you can place the second table at (0,3)(4,5)(0, 3)-(4, 5).

In the second test case, there is no way to fit both tables in the room without intersecting.

In the third test case, you can move the first table by (0,2)(0, 2), so the lower left corner will move from (0,3)(0, 3) to (0,5)(0, 5).


题目大意

W×HW\times H的空间要放两张桌子。已经有一张桌子左下角和右上角坐标分别是(x1,y1)(x1,y1)(x2,y2)(x2,y2),想再放一张w×hw\times h的桌子,不能旋转但能挪动第一张桌子,问第一张桌子至少移动多远。

解题思路

这题图片具有一定的干扰性。图片把桌子向右上方移动了,但是桌子可是方方正正的啊,并且没有斜边。所以要移动最小距离,要么只水平方向上移动,要么只竖直方向上移动。

也就是说把第二张桌子贴着墙角放就最优了。

我们只需要模拟4个角落,看看原本的那张桌子会不会出界就行了。


AC代码

#include <bits/stdc++.h>
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
#define dbg(x) cout << #x << " = " << x << endl
#define fi(i, l, r) for (int i = l; i < r; i++)
#define cd(a) scanf("%d", &a)
typedef long long ll;
int main()
{
    int N;
    cin>>N;
    while(N--)
    {
        int W,H;
        int x1,x2,y1,y2;
        int w,h;
        cin>>W>>H>>x1>>y1>>x2>>y2>>w>>h;
        int m=INT_MAX;
        // ↙ 放左下角
        int tx=w,ty=h; // 这张桌子的右上顶点的x,y坐标
        if(x1<tx) // 先考虑水平移动,如果原来那张桌子x坐标小于tx,原来的桌子就必须往右移
        {
            int moveX=tx-x1; // 要右移的距离
            if(x2+moveX<=W) // 右移后桌子的有边界的x是否出界
            {
                m=min(m,moveX); // 不出界更新答案最小值
            }
        }
        else // 否则本来就不需要水平移动(不冲突)
        {
            m=0; // 答案就是0
        }
        if(y1<ty) // 同理考虑向上移动
        {
            int moveY=ty-y1;
            if(y2+moveY<=H)
            {
                m=min(m,moveY);
            }
        }
        else
        {
            m=0;
        }

        // ↘ 第二张桌子移动到右下角
        tx=W-w,ty=h; // 第二张桌子左上角顶点的坐标
        if(x2>tx) // 第一张桌子水平移动
        {
            int moveX=x2-tx;
            if(x1-moveX>=0)
            {
                m=min(m,moveX);
            }
        }
        else
        {
            m=0;
        }
        if(y1<ty) // 竖直移动
        {
            int moveY=ty-y1;
            if(y2+moveY<=H)
            {
                m=min(m,moveY);
            }
        }
        else
        {
            m=0;
        }
        
        // ↖ 第二张桌子移动到左上角
        tx=w,ty=H-h; // 第二张桌子右下角的坐标
        if(x1<tx) // 第一张桌子水平移动
        {
            int moveX=tx-x1;
            if(x2+moveX<=W)
            {
                m=min(m,moveX);
            }
        }
        else
        {
            m=0;
        }
        if(y2>ty) // 竖直移动
        {
            int moveY=y2-ty;
            if(y1-moveY>=0)
            {
                m=min(m,moveY);
            }
        }
        else
        {
            m=0;
        }
        
        // ↗ 移动到右上角
        tx=W-w,ty=H-h; // 第二张桌子左下角的坐标
        if(x2>tx) // 第一张水平移动
        {
            int moveX=x2-tx;
            if(x1-moveX>=0)
            {
                m=min(m,moveX);
            }
        }
        else
        {
            m=0;
        }
        if(y2>ty) // 竖直移动
        {
            int moveY=y2-ty;
            if(y1-moveY>=0)
            {
                m=min(m,moveY);
            }
        }
        else
        {
            m=0;
        }
        if(m==INT_MAX)puts("-1");
        else printf("%d\n",m);
    }
    return 0;
}

优化

其实不难发现其中四个角落,每个角落都判断第一张桌子的水平或竖直移动,一共判断了8次。但是其中分别有2种情况是相同的(代码重复率太高)。其实只用判断4次就够了。

同步发文于我的CSDN,原创不易,转载请附上原文链接哦~
Tisfy:letmefly.blog.csdn.net/article/det…