链接:https://www.nowcoder.com/questionTerminal/d3f26db0325444078717cc802e0056d8
来源:牛客网
小易正在玩一款新出的射击游戏,这个射击游戏在一个二维平面进行,小易在坐标原点(0,0),平面上有n只怪物,每个怪物有所在的坐标(x[i], y[i])。小易进行一次射击会把x轴和y轴上(包含坐标原点)的怪物一次性消灭。
小易是这个游戏的VIP玩家,他拥有两项特权操作:
1、让平面内的所有怪物同时向任意同一方向移动任意同一距离
2、让平面内的所有怪物同时对于小易(0,0)旋转任意同一角度
小易要进行一次射击。小易在进行射击前,可以使用这两项特权操作任意次。
小易想知道在他射击的时候最多可以同时消灭多少只怪物,请你帮帮小易。
如样例所示:
所有点对于坐标原点(0,0)顺时针或者逆时针旋转45°,可以让所有点都在坐标轴上,所以5个怪物都可以消灭。
输入描述:
输入包括三行。
第一行中有一个正整数n(1 ≤ n ≤ 50),表示平面内的怪物数量。
第二行包括n个整数x[i](-1,000,000 ≤ x[i] ≤ 1,000,000),表示每只怪物所在坐标的横坐标,以空格分割。
第二行包括n个整数y[i](-1,000,000 ≤ y[i] ≤ 1,000,000),表示每只怪物所在坐标的纵坐标,以空格分割。
输出描述:
输出一个整数表示小易最多能消灭多少只怪物。
示例1
输入
5
0 -1 1 1 -1
0 -1 -1 1 1
输出
5
分析
题目等价于,找一个十字架能够尽可能多的覆盖所有节点。
考虑到一根线至少能够覆盖到两个点,再加一根垂直于这条线至少能够覆盖3个点,在此基础上进行遍历。对任意三个点,我们选择其中两个点做一条直线(三种情况),对于第三个点,我们做一条垂线到这条直线上。这样的十字架已经经过了三个点。对于剩下的点,我们判断是否在这个十字架上。要判断是否在十字架上,首先判断是否和第一条直线在同一条直线上。否则,判断这个点和第三个点所构成的直线是否和第二条直线垂直。
当点数小于等于3个点,则可以把所有点都覆盖到。
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
struct point{
int x = 0;
int y = 0;
};
bool is_sameline(point p1, point p2, point p3){
return ((p1.x - p2.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p2.y)) == 0;
}
bool is_vertical(point p1, point p2){
return (p1.x * p2.x + p1.y * p2.y) == 0;
}
bool is_vertical(point p1, point p2, point p3, point p4){
point v1, v2;
v1.x = p1.x - p2.x;
v1.y = p1.y - p2.y;
v2.x = p3.x - p4.x;
v2.y = p3.y - p4.y;
return is_vertical(v1, v2);
}
int main()
{
int n, ret = 0;
cin >> n;
point inputs[n];
for (int i = 0; i < n; i++)
cin >> inputs[i].x;
for (int i = 0; i < n; i++)
cin >> inputs[i].y;
if (n < 4)
{
cout << n << endl;
return 0;
};
vector<int> select = {1, 1, 1};
for (int i = 0; i < n - 3; i++)
select.push_back(0);
do
{
vector<point> shizi;
for (int i = 0; i < n; i++)
{
if (select[i])
{
shizi.push_back(inputs[i]);
}
}
vector<vector<point>> status;
status.push_back({shizi[0], shizi[1], shizi[2]});
status.push_back({shizi[0], shizi[2], shizi[1]});
status.push_back({shizi[1], shizi[2], shizi[0]});
for (auto points : status)
{
int count = 0;
for (int i = 0; i < n; i++)
{
if (!select[i])
{
if (is_sameline(points[0], points[1], inputs[i]))
count++;
if (is_vertical(points[0], points[1], points[2], inputs[i]))
count++;
}
}
ret = max(ret, count);
}
} while (prev_permutation(select.begin(), select.end()));
cout << ret + 3 << endl;
return 0;
}
网友评论