错了一个小地方调了一上午。。跪。。
首先要将所有点离散化,这里注意所有出现的数字最多是不只100个的,因为有x和y两个坐标,所以数组要开200。
特判只有一行的情况。其他时候枚举上下两行,注意此时i!=j,根据left【r】-left【l】+on【l】+on2【r】,维护-left【l】+on【l】的最大值,枚举j,可以在O(n)内求出。
注意l<r。处理的时候枚举r,维护的最大值是max{maxn,on【r-1】-left【r-2】}。这个r-2写成r-1了,调试了好久。。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#define ll long long
#define INF 2139062143
#define inf -2139062144
#define MOD 20071027
#define MAXN 205
using namespace std;
int row[MAXN][MAXN],col[MAXN][MAXN];
int grid[MAXN][MAXN];
struct Point
{
int x,y;
};
int c;
vector<Point> vec;
void Init()
{
set<int> vis;
map<int,int> mp;
vector<int> v;
memset(grid,0,sizeof(grid));
memset(row,0,sizeof(row));
memset(col,0,sizeof(col));
for(int i=0; i<vec.size(); ++i)
{
if(!vis.count(vec[i].x))
{
vis.insert(vec[i].x);
v.push_back(vec[i].x);
}
if(!vis.count(vec[i].y))
{
vis.insert(vec[i].y);
v.push_back(vec[i].y);
}
}
sort(v.begin(),v.end());
c=0;
for(int i=0; i<v.size(); ++i)
mp[v[i]]=++c;
c+=1;
for(int i=0; i<vec.size(); ++i)
grid[mp[vec[i].x]][mp[vec[i].y]]+=1;
for(int i=1; i<=c; ++i)
for(int j=1; j<=c; ++j)
{
row[i][j]=row[i][j-1]+grid[i][j];
col[i][j]=col[i-1][j]+grid[i][j];
}
}
int main()
{
int kase=0,n;
// freopen("outxx.txt","r",stdin);
// freopen("my.txt","w",stdout);
while(scanf("%d",&n)&&n)
{
int x,y;
vec.clear();
set<int> sx,sy;
for(int i=0; i<n; ++i)
{
scanf("%d%d",&x,&y);
vec.push_back(Point {x,y});
}
printf("Case %d: ",++kase);
if(sx.size()==1||sy.size()==1)
{
printf("%d\n",n);
continue;
}
Init();
int ans=0;
bool ok=false;
for(int i=1; i<=c; ++i)
{
for(int j=i+1; j<=c; ++j)
{
int maxn=inf;
for(int r=1; r<=c; ++r)
{
maxn=max(maxn,col[j-1][r-1]-col[i][r-1]-row[i][r-2]-row[j][r-2]);
ans=max(ans,maxn+row[i][r]+row[j][r]+col[j-1][r]-col[i][r]);
}
}
}
printf("%d\n",ans);
}
return 0;
}