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 }