P1227 完美的对称【洛谷算法习题】

📅 2026/7/5 1:17:53 👁️ 阅读次数 📝 编程学习
P1227 完美的对称【洛谷算法习题】

P1227 完美的对称

网页链接

P1227 完美的对称

题目描述

在峰会期间,必须使用许多保镖保卫参加会议的各国代表。代表们除了由他自己的随身保镖保护外,组委会还指派了一些其他的特工和阻击手保护他们。为了使他们的工作卓有成效,使被保卫的人的安全尽可能得到保障,保镖被分配到被保护人的各个方向。

保镖的最佳站立位置应该是这样的:被保护人应站在所有保镖的对称中心。但是,只要被保护人一移动,保镖就很难根据要人的新位置调整位置。大多数的特工都很难对此作出实时调整。

因此,安全部长决定将该过程逆转一下,保镖先站好自己的位置,然后要人在他们的对称中心找到合适的位置。如果要人随便走动,我们就对他的安全不必负责。

你的工作是使这个过程自动操作。给出一组N NN个点(保镖的位置),你要找出它们的对称中心S SS,在这儿被保护人将相对安全。下面以此类推。

首先我们给定一点A AA以及对称中心S SS,点A ′ A'A是点A AAS SS为对称中心形成的像点,即点S SS是线段A A ′ AA'AA的对称中心。

点阵组(X XX)以S SS为中心的像点是由每个点的像点组成的点阵组。X XX是用来产生对称中心S SS的,即点阵X XXS SS为中心的像点的集合即为点阵X XX本身。

输入格式

输入文件第一行是一个整数N NN1 ≤ N ≤ 20000 1\le N\le 200001N20000,接下来的N NN行每行包含用空格隔开的两个整数X i X_iXiY i Y_iYi− 10 5 ≤ X i , Y i ≤ 10 5 -10^5\le X_i,Y_i\le 10^5105Xi,Yi105,表示这组点阵中第i ii个点的笛卡尔坐标值。

因为任何两个保镖都不会站在同一个位置上,所以在给定的作业中,任何两点都不相同。但注意保镖可以站在被保护人相同的位置。

输出格式

输出文件仅有一行。如果给定的点阵能产生一个对称中心,则输出V.I.P. should stay at ( x , y ). \texttt{V.I.P. should stay at (}x\texttt{,}y\texttt{).}V.I.P. should stay at (x,y).,其中x xxy yy代表中心的笛卡尔坐标值,格式为四舍五入保留至小数点后一位。

如果该组点阵无对称中心,输出This is a dangerous situation!,注意输出时除了两个单词之间用一个空格隔开外,不要输出多余空格。

输入输出样例 #1

输入 #1

8 1 10 3 6 6 8 6 2 3 -4 1 0 -2 -2 -2 4

输出 #1

V.I.P. should stay at (2.0,3.0).

说明/提示

JSOI2008 第二轮。

解题思路

本题核心是点集中心对称判定 + 排序验证,快速求解对称中心。若点集存在中心对称点,对称中心必然是排序后首尾两点的中点(最外侧点两两对称)。解题步骤:首先将所有点按坐标排序,固定首尾点的中点为候选对称中心;随后遍历点集,验证第i个点与第n-i+1个点是否均关于该候选中心对称;若所有点对均满足对称条件,则该点为合法中心,否则点集无对称中心。算法时间复杂度为O ( n log ⁡ n ) O(n\log n)O(nlogn)(主要来自排序),完美适配n ≤ 20000 n≤20000n20000的数据规模,验证过程为线性遍历,高效稳定。

总结

核心逻辑:利用中心对称性质,通过排序确定候选中心,逐点验证对称性。
关键操作:点坐标排序、候选中心计算、对称点对校验。
效率保障:排序+线性遍历,时间复杂度低,轻松处理大数据量的点集。

代码内容

#include<bits/stdc++.h>usingnamespacestd;#defineendl'\n'typedeflonglongll;typedefunsignedlonglongull;typedefvector<vector<ll>>vvt;typedefpair<ll,ll>pll;constll N=1e3+10;constll INF=1e18;constll M=1e6+10;constll mod=1e9+7;structP{doublex,y;};boolcmp(P&u,P&v){if(u.y==v.y)returnu.x<v.x;returnu.y<v.y;}intmain(){ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);cout<<fixed<<setprecision(1);ll n;cin>>n;vector<P>a(n+1);for(ll i=1;i<=n;i++)cin>>a[i].x>>a[i].y;sort(a.begin()+1,a.end(),cmp);doublecx=(a[1].x+a[n].x)/2.0;doublecy=(a[1].y+a[n].y)/2.0;for(ll i=2;i<=n/2;i++){doubletx=(a[i].x+a[n-i+1].x)/2.0;doublety=(a[i].y+a[n-i+1].y)/2.0;if(cx!=tx||cy!=ty){cout<<"This is a dangerous situation!";return0;}}cout<<"V.I.P. should stay at ("<<cx<<","<<cy<<").";return0;}