• 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.
    ");
    }
  • 相关阅读:
    触摸屏与usb鼠标同时支持
    QT国际化(lupdate/linguits/lrelease)生成.ts,转换成.qm方法
    Qt5 使用lambda
    c++中lambda表达式的用法
    异或运算的作用
    函数指针和指针函数用法和区别
    前端html页面学习---html部分
    二:maven构建module
    一:使用maven构建项目
    maven项目发布到tomcat后没有lib目录解决方案
  • 原文地址:https://www.cnblogs.com/Norlan/p/4747209.html
Copyright © 2020-2023  润新知