zoukankan      html  css  js  c++  java
  • poj3349(哈希+链地址法)

    给出N个六边形的6个边长,问其中是否有完全相同的两个六边形,完全相同包括边的长度和位置都要相同。边给出的顺序是逆时针或者顺时针的。

    给每个6边形一个哈希值,方法是对6条边长度的平方和取模

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn = 1e6;
    const int mod = 999983;//100W以内的大素数
    typedef long long LL;
    
    int n;
    char s[100010][10];
    int hash[maxn],next[maxn];
    
    bool judge(int a,int b)
    {
        int i,j,k;
        for(i = 0; i < 6; ++i)//串的起始位置
        {
            for(j = i,k = 0; k < 6; ++k,j = (j+1)%6)//顺时针
                if(s[a][k] != s[b][j]) break;
            if(k == 6) return true;
            for(j = i,k = 0; k < 6; ++k, j = (j+5)%6)//逆时针
                if(s[a][k] != s[b][j]) break;
            if(k == 6) return true;
        }
        return false;
    }
    
    int main()
    {
        //freopen("in","r",stdin);
        scanf("%d",&n);
        bool flag = false;
        for(int i = 1; i <= n; ++i)
        {
            int x = 0,u;
            for(int j = 0; j < 6; ++j)
            {
                scanf("%d",&s[i][j]);
                x = (int)((x+(LL)s[i][j]*(LL)s[i][j])%mod);//防止溢出
            }
            u = hash[x];//hash【】里面存的是哈希值对应的某一行的行号
            while(u){
                if(judge(i,u)) {flag = true;break;}//只要u!=0,说明之前出现过这个hash值,则可能出现相同的六边形,判断一下
                u = next[u];//沿着“链表”往下走
            }
            if(flag)break;
            next[i] = hash[x];//类似链表的插入方法,把hash值相同的放在一起,方便以后用next可以遍历到所有hash相同的边
            hash[x] = i;//更新表头
        }
        if(flag) printf("Twin snowflakes found.
    ");
        else printf("No two snowflakes are alike.
    ");
    }
  • 相关阅读:
    优化输出质数
    springboot嵌入式Servlet容器自动配置原理
    springboot中配置servlet三大组件
    springboot中springmvc的自定义配置
    springboot实现自定义国际化
    springboot错误处理机制及自定义错误处理
    SpringBoot对静态资源的映射规则
    docker中启动mysql容器
    Java函数式编程(一)
    java并发编程之美——高级篇(三)
  • 原文地址:https://www.cnblogs.com/Norlan/p/4747209.html
Copyright © 2011-2022 走看看