1455E Four Points(思维+全排列)

Educational Codeforces Round 99 (Rated for Div. 2)

E. Four Points

题面:Four Points

题意:二维平面上有四个点 p 1 , p 2 , p 3 p_1, p_2, p_3 p1​,p2​,p3​ 和 p 4 p_4 p4​,现在想让这四个点形成与坐标轴平行的正方形(正方形也可以是一个点),每次操作可以让其中一个点往上下左右移动一个单位距离,问最小的操作次数是多少。

范围: p i = ( x i , y i ) , 0 ≤ x , y ≤ 1 e 9 p_i = (x_i, y_i), 0 \le x, y \le 1e9 pi​=(xi​,yi​),0≤x,y≤1e9。

分析: 先简化问题,假设这四个点分别对应正方形的 a , b , c , d a, b, c, d a,b,c,d 如下四个顶点,那么如何快速求得答案,即这四个点分别到 a , b , c , d a, b, c, d a,b,c,d 的曼哈顿距离之和。

首先,不失一般性,我们可以认为点先到达线段所在直线上,再移动到最终的顶点位置,假设我们需要确定线段 a b ab ab,当这条线段位于 p 1 p_1 p1​ 与 p 2 p_2 p2​ 两个点的中间的时候, p 1 p_1 p1​ 和 p 2 p_2 p2​ 到该线段的距离和最小,选择区间为 [ p 1 . x , p 2 . x ] [p_1.x, p_2.x] [p1​.x,p2​.x]。

对于另一条边 c d cd cd 也是同样的道理, c d cd cd 的选择区间为 [ p 3 . x , p 4 . x ] [p_3.x, p_4.x] [p3​.x,p4​.x] 中时 p 3 p_3 p3​ 和 p 4 p_4 p4​ 到 c d cd cd 的距离和最小。

在选定 a b ab ab 和 c d cd cd 之后就可以确定正方形的边长为 l e n ∈ [ l e n 1 , l e n 2 ] len \in [len_1, len_2] len∈[len1​,len2​] 如下图所示。

同理,选定 a c ac ac 和 b d bd bd 两条水平的边也可以确定正方形的边长 l e n ′ ∈ [ l e n 3 , l e n 4 ] len' \in [len_3, len_4] len′∈[len3​,len4​]。

当区间 [ l e n 1 , l e n 2 ] [len_1, len_2] [len1​,len2​] 与区间 [ l e n 3 , l e n 4 ] [len_3, len_4] [len3​,len4​] 有交集的时候,说明存在一个边长 l e n len len 同时满足两者的最优解,输出距离和即可。如果没有交集的话,不失一般性,假设 l e n 3 > l e n 2 len_3 > len_2 len3​>len2​,即区间 [ l e n 3 , l e n 4 ] [len_3, len_4] [len3​,len4​] 在区间 [ l e n 1 , l e n 2 ] [len_1, len_2] [len1​,len2​] 的右边如下图。

显然,这时只有当正方形的边长为 l e n 2 len_2 len2​ 或者 l e n 3 len_3 len3​ 时才能得到整体的最优解,但是需要多支出 2 ∗ d i s t 2 * dist 2∗dist 的代价,因为需要 2 2 2 个点多移动 d i s t dist dist 的距离。

到此,固定了 p 1 , p 2 , p 3 , p 4 p_1, p_2, p_3, p_4 p1​,p2​,p3​,p4​ 四个点与正方形四个顶点的对应关系下的最优解问题已经解决,但是实际上的对应关系我们还无法确定,因为只有四个点,直接进行 n e x t _ p e r m u t a t i o n next\_permutation next_permutation 全排列枚举取最优解即可。

Code

#include <bits/stdc++.h>
#define int long long
#define double long double
using namespace std;inline int read()
{int s = 0, w = 1;char ch = getchar();while (ch < '0' || ch > '9'){if (ch == '-')w = -1;ch = getchar();}while (ch >= '0' && ch <= '9')s = s * 10 + ch - '0', ch = getchar();return s * w;
}const int MAXN = 4 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double eps = 1e-9;
const double PI = acos(-1.0);int n, m, k;struct Point
{int x, y;
} points[MAXN];int arr[MAXN];int calc()
{Point ld = points[arr[0]], lu = points[arr[1]],rd = points[arr[2]], ru = points[arr[3]];int seg_xl = min(abs(max(ld.x, lu.x) - min(rd.x, ru.x)), abs(min(ld.x, lu.x) - max(rd.x, ru.x)));int seg_xr = max(abs(max(ld.x, lu.x) - min(rd.x, ru.x)), abs(min(ld.x, lu.x) - max(rd.x, ru.x)));int seg_yl = min(abs(max(ld.y, rd.y) - min(lu.y, ru.y)), abs(min(ld.y, rd.y) - max(lu.y, ru.y)));int seg_yr = max(abs(max(ld.y, rd.y) - min(lu.y, ru.y)), abs(min(ld.y, rd.y) - max(lu.y, ru.y)));int res = max(ld.x, lu.x) - min(ld.x, lu.x) + max(rd.x, ru.x) - min(rd.x, ru.x) +max(ld.y, rd.y) - min(ld.y, rd.y) + max(lu.y, ru.y) - min(lu.y, ru.y) +2 * max(0ll, max(seg_xl, seg_yl) - min(seg_xr, seg_yr));return res;
}signed main()
{int T = read();while (T--){for (int i = 0; i < 4; i++){points[i].x = read(), points[i].y = read();}for (int i = 0; i < 4; i++){arr[i] = i;}int ans = -1;do{if (ans < 0) ans = calc();else ans = min(ans, calc());} while (next_permutation(arr, arr + 4));cout << ans << endl;}return 0;
}

【END】感谢观看

1455E Four Points(思维+全排列)相关推荐

  1. CodeForces - 1455E Four Points(数学+几何)

    题目链接:点击查看 题目大意:给出四个点,问最少移动多少步,可以使得四个点围成的矩形是正方形(这里的正方形允许退化成点) 题目分析:比赛时写了个三分,然鹅又双叒叕不知道哪里写崩了,还是太鶸了呀 首先对 ...

  2. 【Codeforces - 1000C】Covered Points Count(思维,离散化,差分)

    题干: You are given nn segments on a coordinate line; each endpoint of every segment has integer coord ...

  3. 【CodeForces - 1047B 】Cover Points (数学,构造,思维)

    题干: There are nn points on the plane, (x1,y1),(x2,y2),-,(xn,yn)(x1,y1),(x2,y2),-,(xn,yn). You need t ...

  4. HDU 4489 找出n!个全排列数中的“波浪数” dp 思维,全排列

    这题关键还是在于找出dp的转移方程,这题是从第n个数在前n-1个数的位置中入手,然后把"波浪数"分成两派.理解起来不困难,但是要自己想到的话,其中的思维一片也不能断掉,尤其是要找到 ...

  5. 2020牛客多校第3场:[Points Construction Problem + 思维题+构造]

    题目链接 题目大意:就是给你n个边长为1的正方形,要求用这些正方形拼成周长为m的图形,并输出这些正方形的坐标,如果没有输出No 首先如果这些正方形都零散分布那么周长就是4∗n4*n4∗n,如果将这些正 ...

  6. CodeForces - 1000C Covered Points Count(差分+思维)

    题目链接:点击查看 题目大意:给出n个区间,现在要求输出覆盖次数为1,2,3....n-1,n的点分别有多少个 题目分析:一开始看到区间问题想用线段树去做,但想了想又可以直接用差分去做,不过因为数比较 ...

  7. 【ZOJ - 4032】Magic Points (思维,几何,构造)

    题干: 解题报告: 想到了,这样绕圈构造.但是这样有个问题,最后一个点如何构造. 刚开始想的是n=奇数  ,  就8 10 这样的连一条,n=偶数  就8 11 这样的连一条,随便构造一下就行,但是发 ...

  8. 字符串的全排列和组合算法

    转载http://blog.csdn.net/hackbuteer1/article/details/7462447,感谢Hackbuteer1. 全排列在笔试面试中很热门,因为它难度适中,既可以考察 ...

  9. 149. Max Points on a Line同一条线上的最多点数

    [抄题]: Given n points on a 2D plane, find the maximum number of points that lie on the same straight ...

最新文章

  1. 我对虚拟化的认识(一)
  2. python小项目案例-拯救Python新手的几个项目实战
  3. Android Studio下gradle环境搭建
  4. iOS8中UITableVIew分割线短的问题
  5. linux vi/vim 的命令
  6. 嵌入式软件设计之设计模式
  7. netty面试题及答案
  8. win10 网络发现 打开保存后,自动关闭
  9. pc端自适应不同屏幕
  10. Photoshop教程:10秒闪电搞定照片构图
  11. html显示当前脚本错误,访问网页总是提示当前网页脚本发生错误怎么办?
  12. 2011-1 开篇,要确定好方向
  13. 设置Windows控制台颜色
  14. 美团配送 二面(40min) Java后端 暑期实习面经
  15. 乱斗西游2辅助 强力辅助排行一览
  16. web前端需要学习什么?
  17. 五折交叉验证/K折交叉验证, python代码到底怎么写
  18. python读取文件详解_python 文件读取方法详解
  19. Python启发式算法中爬山法的讲解及解方程问题实战(超详细 附源码)
  20. web图片裁切插件 cropper.js 详细介绍

热门文章

  1. 手写FSM实现小怪状态管理
  2. 记录 Ubuntu 下 Audio Jack(耳机插孔) 引起的 kworker CPU 高占用Bug
  3. linux rz工具怎么用,Linux和Windows间文件传输工具rz/sz(lrz/lsz) 介绍
  4. 入门Webpack,看这篇就够了
  5. mysql 获取分区的最大值_MySQL分区表测试
  6. Python编程读书笔记
  7. fable樱桃php频道,【爵士乐利器】Fable Sounds Broadway Big Band v1.3 97.7G
  8. 刷题28-有效的变位词
  9. MySQL中alter命令知识
  10. Pandas多条件筛选