题目大意
- 给你一块m*n的矩阵,以及num个点的坐标,含有点的数量最多的直线所含有的点的数量。
- 要求:直线上的点间距要相等,不足3个点的记为0。若前k个点在矩阵内,第k+1个点的坐标也在矩阵内,但矩阵中不存在该点,则此直线无效。
分析
- 先对坐标按x排序,若x相等,则按y排序
- 枚举每条直线上的**前两个点**s1 ,s2即可。计算出步长lenx = s2.x - s1.x , leny = s2.y - s1.y
- 由步长计算出下一个点的坐标,若该点在矩阵外,则可返回答案。否则就要判断矩阵内是否存在该点。若存在则依次搜索下去,直到下一个点的坐标出现在矩阵外,或者矩阵内不存在该点。
代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 5005;
struct Node {
int x , y;
bool operator < (const Node &rhs) const {
return (x < rhs.x) || (x == rhs.x && y < rhs.y);
}
}node[maxn];
int m , n , num;
int maze[maxn][maxn];
bool judge(Node const &s1 , Node const &s2)
{
int lenx = s2.x - s1.x , leny = s2.y - s1.y;
int tx = s1.x - lenx , ty = s1.y - leny;
if(tx > 0 && tx <= m && ty > 0 && ty <= n) return false;
return true;
}
int DFS(Node const &s1 , Node const &s2 , int len)
{
Node s;
int lenx = s2.x - s1.x , leny = s2.y - s1.y;
s.x = s2.x + lenx , s.y = s2.y + leny;
if(s.x <= 0 || s.x > m || s.y <= 0 || s.y > n) return len > 2 ? len : 0;
if(maze[s.x][s.y]) return DFS(s2 , s , len+1);
return 0;
}
int main()
{
ios::sync_with_stdio(false);
while(cin >> m >> n)
{
cin >> num;
memset(maze , 0 , sizeof(maze));
for(int i = 0; i < num; i++) {
cin >> node[i].x >> node[i].y;
maze[node[i].x][node[i].y] = 1;
}
sort(node , node + num);
int ans = 0;
for(int i = 0; i < num; i++) for(int j = i + 1; j < num; j++) {
Node s1 = node[i] , s2 = node[j];
if(!judge(s1 , s2)) continue;
ans = max(ans , DFS(s1 , s2 , 2));
}
cout << ans << endl;
}
return 0;
}