zoukankan      html  css  js  c++  java
  • 【POJ3349 Snowflake Snow Snowflakes】【Hash表】

    最近在对照省选知识点自己的技能树 今天是Hash

    题面

    大概是给定有n个6元序列
    定义两个序列相等 当两个序列各自从某一个元素开始顺时针或者逆时针旋转排列能得到两个相同的序列
    求这n个6元序列中是否有相等的序列

    解释相等序列的样例

    顺时针:如 1 2 3 4 5 6 与 2 3 4 5 6 1 相等
    逆时针:如 1 2 3 4 5 6 与 6 5 4 3 2 1 相等

    算法

    对于各种类型的数列 字符串是否相等问题我们都可以用Hash解决
    我们对一个序列A 定义其哈希值为 (H(A) = (sum^{6}_{j = 1}A_{i,j} + prod^{6}_{j = 1}A_{i,j}) mod P)
    P的取值稍后讨论
    我们知道对于组成数字一样的两个序列A和B 显然有(H(A) = H(B))
    我们用领接表来存储这些哈希值相等的序列在总序列中的下标,然后我们把当前序列A与在哈希表中哈希值同A一样的序列进行比较即可
    如果没有匹配的 我们则把A的首个元素下标 存入哈希表

    P的取值

    在哈希表中 我们通常取P与数据范围N接近的质数 这样可以让哈希表尽量的均匀 可以提高查找效率 这里最大的数据范围是 600000 我们取(P = 517619)

    代码

    #include <iostream>
    #include <cstdio>
    #define ll long long
    #define M 600010
    #define MOD 517619
    using namespace std;
    ll num[M], n, head[M];
    struct P {
        ll biao, next;
    } lian[M];
    bool cheek(ll n1, ll n2) {
        bool p;
        for (ll i = 1; i <= 6; i++)  //顺
        {
            p = 1;
            for (ll j = 1; j <= 6; j++) {
                ll now = n1 + (i + j - 1) % 6;
                if (num[now] != num[n2 + j - 1]) {
                    p = 0;
                    break;
                }
            }
            if (p)
                return 1;
        }
        for (ll i = 1; i <= 6; i++)  //逆
        {
            p = 1;
            for (ll j = 1; j <= 6; j++) {
                ll now = n1 + (i + j - 1) % 6;
                if (num[now] != num[n2 + 6 - j]) {
                    p = 0;
                    break;
                }
            }
            if (p)
                return 1;
        }
        return 0;
    }
    bool insert(ll num, ll front) {
        ll now = head[num];
        if (now == 0) {
            lian[++lian[0].biao].biao = front;
            lian[lian[0].biao].next = head[num];
            head[num] = lian[0].biao;
            return 0;
        } else
            for (; now; now = lian[now].next) {
                if (cheek(lian[now].biao, front))
                    return 1;
            }
        lian[++lian[0].biao].biao = front;
        lian[lian[0].biao].next = head[num];
        head[num] = lian[0].biao;
        return 0;
    }
    int main() {
        scanf("%lld", &n);
        for (ll i = 1; i <= 6 * n; i += 6) {
            ll sum = 0;
            ll cheng = 1;
            for (ll j = 1; j <= 6; j++) {
                scanf("%lld", &num[i + j - 1]);
                sum = (sum + num[i + j - 1]) % MOD;
                cheng = (cheng * num[i + j - 1]) % MOD;
            }
            ll key = (sum + cheng) % MOD;
            if (insert(key, i)) {
                puts("Twin snowflakes found.");
                return 0;
            }
        }
        puts("No two snowflakes are alike.");
    }
    
    ```(奇怪 代码块渲染出了点问题)
  • 相关阅读:
    day113-django-Form组件常用字段和参数
    day112-django-Form组件-ajax提交给后台的Form验证
    day110-django-中间件和(socket:wsgiref、uwsgi)
    day111-django-初识Form组件(验证登录信息)
    day109-django-多对多、session保存用户信息到数据库和从数据库获取用户信息
    day108-django-路由分发、动态路由、伪静态、根据名称反向生成url
    软件测试基础
    Python并发编程之:多进程
    进程介绍(理论部分)
    网络编程
  • 原文地址:https://www.cnblogs.com/dixiao/p/13741741.html
Copyright © 2011-2022 走看看