原题链接:https://blog.csdn.net/weixin_43773540/article/details/105388870
运行时间限制:2 s
题目描述:
给出平面上 N 个点的坐标点集, 求这 N 个点有多少条整体对称轴。整体对称是指一条直线,对于每个点,都能找到点集的一个点与他关于这条直线对称。
输入
第一行是一个整数N,表示点的个数
接下来 N 行,每行两个整数 X, Y,表示点的坐标
2 <= N <= 1000
-10000 <= X, Y <= 10000
输出
输出点集的整体对称轴有多少条
样例输入
4
0 0
0 1
1 0
1 1
样例输出
4
1.思路
1.1对称轴的定义
①对称轴上的任意一点与对称点的距离相等;
②对称点所连线段被对称轴垂直平分。
1.2根据定义想象情况
对于对称图的点
1.点在对称轴外就必须有一点与之符合对称轴定义的点
2.点在对称轴上
2.设限
让所有点排列组合
两两进行连线
如果是单数则判断最后剩下的是不是在对称轴上
有符合下列情况的就累计一条对称轴
当有多条对称轴时,所有对称轴必定相交于一点
所以对称轴的斜率k种类 = 对称轴数,无需求直线定义公式【Y= k × X + d】中的偏移量d
3.代码
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows;
namespace test
{
class Program
{
static void Main(string[] args)
{
List<string> readLineStrings = new List<string> {
// 方便测试不写输入及输入验证
"4",
"0 0",
"2 0",
"0 2",
"2 2",
"3 1",// 测试排除
};
int N = int.Parse(readLineStrings[0]);
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
readLineStrings.RemoveAt(0);
Point[] points = new Point[readLineStrings.Count];// 输入的坐标点集合
int i = 0;
foreach (string str in readLineStrings)
{
string[] x_y = str.Split();
Point newPoint = new Point(double.Parse(x_y[0]), double.Parse(x_y[1]));
if (!points.Contains(newPoint))
points[i++] = newPoint;
}
List<Point[]> pointsPermutation = PermutationAndCombination<Point>.GetPermutation(points);// 获取所有排列组合
List<Point> symmetryAxises = new List<Point>();// 对称轴斜率种类
foreach (Point[] permutation in pointsPermutation)// 逐个遍历排列组合
{
List<Point> slopes = new List<Point>();// 斜率种类,第一种必定是两点相连的,如果有第二种必定是与对称轴重合
List<Point> midPoints = new List<Point>();// 中点数
Queue<Point> permutationQueue = new Queue<Point>(permutation);
bool hasFind = true;// 这个排列组合是否找到对称轴
while (permutationQueue.Count > 0)
{
Point p1 = permutationQueue.Dequeue();
Point midPoint = p1;// 中点坐标默认是p1
if (permutationQueue.Any())// 讨论斜率,确定最多只有2种斜率,而且如果有必定是相互垂直
{
Point p2 = permutationQueue.Dequeue();
midPoint = new Point((p1