题意
传送门 POJ 1054
题解
枚举顶点对作为线段端点 O ( n 2 ) O(n^2) O(n2) ,只有线段最长的边才是可能解;以端点间距为步长,通过判断端点是否在边界上(路径横穿地图),即可判断是否需要从另一个端点开始统计点数;若一开始使顶点有序,可只判断一侧端点。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
#include <map>
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define abs(x) ((x) < 0 ? -(x) : (x))
#define INF 0x3f3f3f3f3f3f3f3f
#define delta 0.85
using namespace std;
struct P{
int x, y;
P(){}
P(int x, int y) : x(x), y(y) {}
P operator + (P p){
return P(x + p.x, y + p.y);
}
P operator - (P p){
return P(x - p.x, y - p.y);
}
P operator * (int d){
return P(x * d, y * d);
}
bool operator < (const P& p) const{
if(x == p.x){
return y < p.y;
}
return x < p.x;
}
};
#define maxn 5005
int R, C, N;
bool mp[maxn][maxn];
P ps[maxn];
void solve(){
sort(ps, ps + N);
int res = 0;
for (int i = 0; i < N; i++){
for (int j = i + 1; j < N; j++){
P step = ps[i] - ps[j], pre = ps[i] + step;
// 非最长线段端点
if(pre.x > 0 && pre.x <= R && pre.y > 0 && pre.y <= C){
continue;
}
P tmp = ps[j] - step * res;
// 非最优解
if(!(tmp.x > 0 && tmp.x <= R && tmp.y > 0 && tmp.y <= C)){
continue;
}
int cnt = 0;
P nxt = ps[j] - step;
while(nxt.x > 0 && nxt.x <= R && nxt.y > 0 && nxt.y <= C && mp[nxt.x][nxt.y]){
++cnt;
nxt = nxt - step;
}
if(nxt.x > 0 && nxt.x <= R && nxt.y > 0 && nxt.y <= C){
cnt = 0;
}
res = max(res, cnt);
}
}
printf("%d\n", res == 0 ? 0 : res + 2);
}
int main(){
while(~scanf("%d%d", &R, &C)){
scanf("%d", &N);
memset(mp, 0, sizeof(mp));
for (int i = 0; i < N; i++){
int x, y;
scanf("%d%d", &x, &y);
ps[i] = P(x, y);
mp[x][y] = 1;
}
solve();
}
return 0;
}