今天的网络赛题目,用状态压缩的思想预处理,可以证明出20个点大概不能组成超过100个正方形。于是先预处理所有的正方形,然后0-1背包就可以了。、
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<algorithm>
#include<iostream>
#include<cstring>
#include<fstream>
#include<sstream>
#include<vector>
#include<string>
#include<cstdio>
#include<bitset>
#include<queue>
#include<stack>
#include<cmath>
#include<map>
#include<set>
#define FF(i, a, b) for(int i=a; i<b; i++)
#define FD(i, a, b) for(int i=a; i>=b; i--)
#define REP(i, n) for(int i=0; i<n; i++)
#define CLR(a, b) memset(a, b, sizeof(a))
#define debug puts("**debug**")
#define LL long long
#define PB push_back
#define MP make_pair
#define eps 1e-10
using namespace std;
const int N = 22;
struct Point
{
int x, y;
bool operator < (const Point& rhs) const
{
return x < rhs.x || (x == rhs.x && y < rhs.y);
}
}p[N];
int n, dp[1 << N];
bool vis[1 << N];
vector<int> sqr;
bool ok(int i, int j, int k, int s)
{
return (p[i].x == p[j].x && p[i].y == p[k].y && p[j].y == p[s].y && p[s].x == p[k].x) && (p[k].x - p[i].x == p[j].y - p[i].y);
}
void pre()
{
int i, j, k, s;
sqr.clear();
for(i = 0; i < n; i ++)
for(j = i + 1; j < n; j ++)
for(k = j + 1; k < n; k ++)
for(s = k + 1; s < n; s ++)
if(ok(i, j, k, s))
sqr.PB((1 << i) + (1 << j) + (1 << k) + (1 << s));
}
int main()
{
//freopen("input.txt", "r", stdin);
int i, j, ans;
while(scanf("%d", &n), n > 0)
{
for(i = 0; i < n; i ++)
{
scanf("%d%d", &p[i].x, &p[i].y);
}
sort(p, p + n);
pre();
CLR(dp, -1);
dp[0] = 0, ans = 0;
for(i = 0; i < sqr.size(); i ++)
{
for(j = 0; j < (1 << n); j ++)
{
if(((j & sqr[i]) == 0) && dp[j] != -1)
{
dp[j | sqr[i]] = max(dp[j | sqr[i]], dp[j] + 1);
ans = max(dp[j + sqr[i]], ans);
}
}
}
printf("%d\n", ans * 4);
}
}