CodeForces 303B Rectangle Puzzle II

题意:

给定一个靠着坐标轴长为n,宽为m的矩形和 矩形中的一个点A,求在这个矩形内部一个

长宽比为a/b的小矩形,使这个小矩形的长宽尽量大使点A在小矩形内部,并且点A尽量靠近小矩形的中心

CF的思维题确实牛,让点A尽量靠近小矩形的中心其实是比较障眼法的,让你觉得这个问题又需要考虑

小矩形最大又需要考虑点A的问题,然是考虑这样一个问题,小矩形的大小和点A在小矩形内部,两个问题是否矛盾。

这是解决问题的关键,所以这不仅是思维的难度,也是心理的考验,在思考这个问题之初就默认这两个问题是矛盾的,

为之后的思考就变成了同时考虑两个因素,让问题变难了,所以要细分这个问题,矩形的大小和包括点在其中是不矛盾的!

任何一个小矩形都可以使这个点在包含在其中,所以先直接求这个小矩形的长宽最大值(答案的优先条件),从这个角度题目有一定

的提示,然后接下来的问题就是让这个点尽量的靠近小矩形的中心,这可以O(1)的复杂度办到,直接从点的坐标入手,如果可以直接让其分别在长宽的中点,

如果不能,那就需要一半短一点,另一半长一点,调整一下即可,注意当长度为偶数和奇数时需要分类讨论一下。

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <iostream>
 4 #include <queue>
 5 #include <vector>
 6 #include <algorithm>
 7 #include <stack>
 8 #include <set>
 9 #include <map>
10 #include <math.h>
11 #define pb push_back
12 #define CLR(a) memset(a, 0, sizeof(a));
13 #define MEM(a, b) memset(a, b, sizeof(a));
14 #define fi first
15 #define se second
16 
17 using namespace std;
18 
19 typedef long long ll;
20 
21 const int MAXN = 5007;
22 const int MAXV = 207;
23 const int MAXE = 207;
24 const int INF = 0x3f3f3f3f;
25  
26 
27 int n, m, x, y, a, b;
28 int gcd(int x, int y)
29 {
30     if (y == 0 ) return x;
31     return gcd(y, x%y);
32 }
33 int main()
34 {
35     //freopen("in.txt", "r", stdin);
36     int len, wid;
37     int pw;
38     int up, down, left, right;
39     while (~scanf("%d%d%d%d%d%d", &n, &m, &x, &y, &a, &b))
40     {
41         int GCD = gcd(a, b);
42         a = a/GCD;
43         b = b/GCD;
44         pw = min(n/a, m/b);
45         len = pw*a;
46         wid = pw*b;
47         int d;
48         int half1 = wid / 2, half2 = (wid & 1) ? half1+1 : half1;
49         if (m - y >= half1 && y >= half2)
50         {
51             up = y+half1;
52             down = y-half2;
53         }
54         else if (m - y < half1)
55         {
56             up = m;
57             down = m-half1-half2;
58         }
59         else if (y < half2)
60         {
61             down = 0;
62             up = half1 + half2;
63         }
64         half1 = len/2;
65         half2 = (len & 1) ? half1+1 : half1;
66         if (n-x >= half1 && x >= half2)
67         {
68             left = x - half2;
69             right = x + half1;
70         }
71         else if (n-x < half1)
72         {
73             right = n;
74             left = n-half1-half2;
75         }
76         else if (x < half2)
77         {
78             left = 0;
79             right = half1+half2;
80         }
81         cout << left << " " << down << " " << right << " " << up << endl;
82     }
83     return 0; 
84 }
原文地址:https://www.cnblogs.com/oscar-cnblogs/p/7615301.html