SYSU-7,Gym 100273J, Japanese Writing,hash

题目大意:给你一些笔画(笔画顺序打乱),让你判断两个字是不是相等的。

解:建议如果没看题的去读一读题,两个笔画相等的判断只在于两点之间的相对关系(9个方向)以及笔画的方向(8个),所以我们对每一个笔画根据他的方向压一个hash值(hash掉这个笔画两个点对于所有其他点的方向)。其实判笔画本质是一个图同构问题,类似于给定一个图的所有点的度数,如果度数全部相等,说明我们肯定能找到一个同构的图。

(吐槽一下,本来1A的,结果有几个变量手残打错了debug了半天T T,差点没把20个点的数据画出来

 

#include <cstdio>
#include <string>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <complex>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <deque>
#include <ctime>

using namespace std;

const double EPS = 1e-8;

#define ABS(x) ((x)<0?(-(x)):(x))
#define SQR(x) ((x)*(x))
#define MIN(a,b) ((a)<(b)?(a):(b))
#define MAX(a,b) ((a)>(b)?(a):(b))

#define LSON(x) ((x)<<1)
#define RSON(x) (((x)<<1)+1)
#define LOWBIT(x) ((x)&(-(x)))
#define MAXN 11111
#define VOIDPOINT 0
#define LL long long
#define OO 214748364

#define MAXT 8

const LL MOD = 1e9+7;

LL pre[MAXT], key[MAXT], preT[MAXT], keyT[MAXT];
int m, lastm;
LL poww[MAXN];

struct point{
    int x, y;
    point(int a = 0, int b = 0): x(a), y(b) {}
    void read() {
        scanf("%d%d", &x, &y);
    }
};

int typee(const point &a, const point &b) {
    if (a.x == b.x && b.y > a.y) return 0;
    if (b.x > a.x && b.y > a.y) return 1;
    if (b.x > a.x && b.y == a.y) return 2;
    if (b.x > a.x && b.y < a.y) return 3;
    if (b.x == a.x && b.y < a.y) return 4;
    if (b.x < a.x && b.y < a.y) return 5;
    if (b.x < a.x && b.y == a.y) return 6;
    if (b.x < a.x && b.y > a.y) return 7;
    return 8;
}

struct data{
    point s, t;
    int type;
    data() {}
    void read() {
        s.read(); t.read();
        type = typee(s, t);
    }
    LL hash(const data &rhs) const {
        LL res = 0;
        int now, x, y, z, tt; 
        
//        for (int i = 0; i < m; ++i) if (i != num) {
            x = rhs.type; y = typee(s, rhs.s); z = typee(s, rhs.t);
            tt = x * 81 + y * 9 + z;
            now = poww[tt];
            res = (res + now) % MOD;
//        }

//        for (int i = 0; i < m; ++i) if (i != num) {
            x = rhs.type; y = typee(t, rhs.s); z = typee(t, rhs.t);
            tt = x * 81 + y * 9 + z + 729;
            now = poww[tt];
            res = (res + now) % MOD;
//        } 

        return res;
    }
};

void pree() {
    poww[0] = 1;
    for (int i = 1; i < MAXN; ++i) {
        poww[i] = poww[i-1] * (729);
        poww[i] %= MOD;
    }
}

data a[MAXN];

void init() {
    scanf("%d", &m);
    memset(keyT, 0, sizeof(keyT));
    for (int i = 0; i < m; ++i) {
        a[i].read(); keyT[a[i].type]++;
    }
    for (int i = 0; i < MAXT; ++i) key[i] = 1;
    for (int i = 0; i < m; ++i) {
        LL tmp = 0;
        for (int j = 0; j < m; ++j) if (i != j) {
            tmp += a[i].hash(a[j]);
            tmp %= MOD;
        }
        key[a[i].type] *= tmp;
        key[a[i].type] %= MOD;
    }
}

int main() {    
//    freopen("test.txt", "r", stdin);    
    freopen("japanese.in", "r", stdin);
    freopen("japanese.out", "w", stdout);

    pree();
    int n; scanf("%d", &n);
    for (int tt = 0; tt < n; ++tt) {
        init();
        if (tt == 0) lastm = m;
        if (tt) {
            bool flag = m == lastm;
            for (int i = 0; i < MAXT; ++i) {
                if (pre[i] != key[i] || preT[i] != keyT[i]) {
                    flag = false; break;
                }
            }
            if (flag) puts("CORRECT");
            else puts("INCORRECT");
        }
        if (tt == 0) for (int i = 0; i < MAXT; ++i) pre[i] = key[i], preT[i] = keyT[i];
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}  
Gym 100273J

 

posted @ 2016-07-07 10:07  F.D.His.D  阅读(469)  评论(0编辑  收藏  举报