ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

ABC 207 D - Congruence Points

2022-06-02 18:35:42  阅读:151  来源: 互联网

标签:ABC const sumy 207 sumx int ++ Points return


D - Congruence Points

计算几何

给出两个点集 S,T,判断 S 点集的点是否可以通过平移、绕原点旋转变成 T

  1. 先求出两个点集的重心,将 S,T 中点的坐标都变成相对重心的坐标(也可以认为是平移到重心是原点的地方)

  2. 这时若 S 可旋转变成 T,则就可以

  3. 可枚举 \(S[i]\) 变成 \(T[0]\), 然后求出需要旋转的角度,判断别的点旋转这么多角度是否可以在 T 点集有对应的位置

    注意如果用 \(atan2\) 求夹角,\(T[0]\) 的斜率不能是无穷

复杂度 \(O(n^3)\)

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
typedef long long ll;
const int N = 1e2 + 10;
const double PI = acos(-1);
int n;
using _T = double;

const _T eps = 1e-5;
bool sgn(double x)
{
	if (fabs(x) < eps)
		return 0;
	if (x > 0)
		return 1;
	return -1;
}
template<typename T> struct point
{
	T x, y;
	point(T a = 0, T b = 0) : x(a), y(b) { }
	  bool operator==(const point &a) const {return (abs(x-a.x)<=eps && abs(y-a.y)<=eps);}
    bool operator<(const point &a) const {if (abs(x-a.x)<=eps) return y<a.y-eps; return x<a.x-eps;}
    bool operator>(const point &a) const {return !(*this<a || *this==a);}
    point operator+(const point &a) const {return {x+a.x,y+a.y};}
    point operator-(const point &a) const {return {x-a.x,y-a.y};}
    point operator-() const {return {-x,-y};}
    point operator*(const T k) const {return {k*x,k*y};}
    point operator/(const T k) const {return {x/k,y/k};}
    T operator*(const point &a) const {return x*a.x+y*a.y;}
    T operator^(const point &a) const {return x*a.y-y*a.x;}
    int toleft(const point &a) const {const auto t=(*this)^a; return (t>eps)-(t<-eps);}
    T len2() const {return (*this)*(*this);}
    T dis2(const point &a) const {return (a-(*this)).len2();}
    double len() const {return sqrt(len2());}
    double dis(const point &a) const {return sqrt(dis2(a));}
    double ang(const point &a) const {return acos(max(-1.0,min(1.0,((*this)*a)/(len()*a.len()))));}//夹角
    point rot(const double rad) const {return {x*cos(rad)-y*sin(rad),x*sin(rad)+y*cos(rad)};}//逆时针旋转
    point rot(const double cosr,const double sinr) const {return {x*cosr-y*sinr,x*sinr+y*cosr};}


};

using Point = point<_T>;

int main()
{
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n;
	vector<Point> s(n + 10), t(n + 10);
	int sumx = 0, sumy = 0;
	for (int i = 0; i < n; i++)
	{
		int x, y;
		cin >> x >> y;
		sumx += x, sumy += y;
		x *= n, y *= n;
		s[i] = Point(x, y);
	}
	for (int i = 0; i < n; i++)
		s[i].x -= sumx, s[i].y -= sumy;
	sumx = 0, sumy = 0;
	for (int i = 0; i < n; i++)
	{
		int x, y;
		cin >> x >> y;
		sumx += x, sumy += y;
		x *= n, y *= n;
		t[i] = Point(x, y);
	}
	for (int i = 0; i < n; i++)
		t[i].x -= sumx, t[i].y -= sumy;
	
	for (int i = 0; i < n; i++)
	{
		if (sgn(s[i].x) != 0)
		{
			swap(s[i], s[0]);
			break;
		}
	}
	for (int i = 0; i < n; i++)
	{
		int cnt = 0;
		double ang = atan2(t[i].y, t[i].x) - atan2(s[0].y, s[0].x);
		for (int j = 0; j < n; j++)
		{
			Point w = s[j].rot(ang);
			for (int k = 0; k < n; k++)
			{
				if (w == t[k])
				{
					cnt++;
					break;
				}
			}
		}
		if (cnt == n)
		{
			cout << "Yes" << endl;
			return 0;
		}
	}
	cout << "No" << endl;
	return 0;
}

标签:ABC,const,sumy,207,sumx,int,++,Points,return
来源: https://www.cnblogs.com/hzy717zsy/p/16338703.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有