[hash] PKU 2002 Squares

此题数据范围其实很小,枚举主对角线,求出另两个点的坐标,看是否存在(所有点都不相同);

hash的模版写法:

# include <stdio.h>
# include <string.h>

# define odd(x) (((x)+100000)&0x1)

# define MAXN 1005
# define MOD 10007

int n;
int x[MAXN], y[MAXN];
int head[MOD], next[MAXN];

int hash(int xx, int yy)
{
    int hkey = xx*13131 + yy;
    return (hkey%MOD + MOD)%MOD;
}

void init_hash_table(void)
{
    memset(head, 0, sizeof(head));
}

void insert_hash_table(int i)
{
    int h = hash(x[i], y[i]);
    next[i] = head[h];
    head[h] = i;
}

int lookup_hash_table(int hkey, int xx, int yy)
{
    int u = head[hkey];
    while (u)
    {
        if (x[u]==xx && y[u]==yy) return u;
        u = next[u];
    }
    return 0;
}

void init(void)
{
    int i;
    init_hash_table();
    for (i = 1; i <= n; ++i)
    {
        scanf("%d%d", &x[i], &y[i]);
        insert_hash_table(i);
    }
}

void solve(void)
{
    int i, j, k, ans = 0, xx, yy, t;
    for (i = 1; i < n; ++i)
    for (j = i+1; j <= n; ++j)
    {
        xx = x[i]+x[j]+y[j]-y[i];
        yy = y[i]+y[j]-x[j]+x[i];
        if (odd(xx) || odd(yy)) ;
        else if (k = lookup_hash_table(hash(xx>>1, yy>>1), xx>>1, yy>>1))
        {
            xx = x[i]+x[j]-y[j]+y[i];
            yy = y[i]+y[j]+x[j]-x[i];
            if (odd(xx) || odd(yy)) ;
            else if (lookup_hash_table(hash(xx>>1, yy>>1), xx>>1, yy>>1))
                ++ans;
        }
    }
    printf("%d\n", ans>>1);
}

int main()
{
    while (scanf("%d", &n), n)
    {
        init();
        solve();
    }
    
    return 0;
}

 

posted on 2012-08-23 15:26  getgoing  阅读(235)  评论(0编辑  收藏  举报

导航