1455E Four Points(思维+全排列)
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(思维+全排列)相关推荐
- CodeForces - 1455E Four Points(数学+几何)
题目链接:点击查看 题目大意:给出四个点,问最少移动多少步,可以使得四个点围成的矩形是正方形(这里的正方形允许退化成点) 题目分析:比赛时写了个三分,然鹅又双叒叕不知道哪里写崩了,还是太鶸了呀 首先对 ...
- 【Codeforces - 1000C】Covered Points Count(思维,离散化,差分)
题干: You are given nn segments on a coordinate line; each endpoint of every segment has integer coord ...
- 【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 ...
- HDU 4489 找出n!个全排列数中的“波浪数” dp 思维,全排列
这题关键还是在于找出dp的转移方程,这题是从第n个数在前n-1个数的位置中入手,然后把"波浪数"分成两派.理解起来不困难,但是要自己想到的话,其中的思维一片也不能断掉,尤其是要找到 ...
- 2020牛客多校第3场:[Points Construction Problem + 思维题+构造]
题目链接 题目大意:就是给你n个边长为1的正方形,要求用这些正方形拼成周长为m的图形,并输出这些正方形的坐标,如果没有输出No 首先如果这些正方形都零散分布那么周长就是4∗n4*n4∗n,如果将这些正 ...
- CodeForces - 1000C Covered Points Count(差分+思维)
题目链接:点击查看 题目大意:给出n个区间,现在要求输出覆盖次数为1,2,3....n-1,n的点分别有多少个 题目分析:一开始看到区间问题想用线段树去做,但想了想又可以直接用差分去做,不过因为数比较 ...
- 【ZOJ - 4032】Magic Points (思维,几何,构造)
题干: 解题报告: 想到了,这样绕圈构造.但是这样有个问题,最后一个点如何构造. 刚开始想的是n=奇数 , 就8 10 这样的连一条,n=偶数 就8 11 这样的连一条,随便构造一下就行,但是发 ...
- 字符串的全排列和组合算法
转载http://blog.csdn.net/hackbuteer1/article/details/7462447,感谢Hackbuteer1. 全排列在笔试面试中很热门,因为它难度适中,既可以考察 ...
- 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 ...
最新文章
- 我对虚拟化的认识(一)
- python小项目案例-拯救Python新手的几个项目实战
- Android Studio下gradle环境搭建
- iOS8中UITableVIew分割线短的问题
- linux vi/vim 的命令
- 嵌入式软件设计之设计模式
- netty面试题及答案
- win10 网络发现 打开保存后,自动关闭
- pc端自适应不同屏幕
- Photoshop教程:10秒闪电搞定照片构图
- html显示当前脚本错误,访问网页总是提示当前网页脚本发生错误怎么办?
- 2011-1 开篇,要确定好方向
- 设置Windows控制台颜色
- 美团配送 二面(40min) Java后端 暑期实习面经
- 乱斗西游2辅助 强力辅助排行一览
- web前端需要学习什么?
- 五折交叉验证/K折交叉验证, python代码到底怎么写
- python读取文件详解_python 文件读取方法详解
- Python启发式算法中爬山法的讲解及解方程问题实战(超详细 附源码)
- web图片裁切插件 cropper.js 详细介绍
热门文章
- 手写FSM实现小怪状态管理
- 记录 Ubuntu 下 Audio Jack(耳机插孔) 引起的 kworker CPU 高占用Bug
- linux rz工具怎么用,Linux和Windows间文件传输工具rz/sz(lrz/lsz) 介绍
- 入门Webpack,看这篇就够了
- mysql 获取分区的最大值_MySQL分区表测试
- Python编程读书笔记
- fable樱桃php频道,【爵士乐利器】Fable Sounds Broadway Big Band v1.3 97.7G
- 刷题28-有效的变位词
- MySQL中alter命令知识
- Pandas多条件筛选