字符串哈希-POJ3349-Snowflake Snow Snowflakes

字符串哈希-POJ3349-Snowflake Snow Snowflakes

题目:

有N片雪花,每片雪花由六个角组成,每个角都有长度。

第i片雪花六个角的长度从某个角开始顺时针依次记为ai,1,ai,2,…,ai,6。

因为雪花的形状是封闭的环形,所以从任何一个角开始顺时针或逆时针往后记录长度,得到的六元组都代表形状相同的雪花。

例如ai,1,ai,2,…,ai,6和ai,2,ai,3,…,ai,6,ai,1就是形状相同的雪花。

ai,1,ai,2,…,ai,6和ai,6,ai,5,…,ai,1也是形状相同的雪花。

我们称两片雪花形状相同,当且仅当它们各自从某一角开始顺时针或逆时针记录长度,能得到两个相同的六元组。

求这N片雪花中是否存在两片形状相同的雪花。

输入格式
第一行输入一个整数N,代表雪花的数量。

接下来N行,每行描述一片雪花。

每行包含6个整数,分别代表雪花的六个角的长度(这六个数即为从雪花的随机一个角顺时针或逆时针记录长度得到)。

同行数值之间,用空格隔开。

输出格式
如果不存在两片形状相同的雪花,则输出:

No two snowflakes are alike.

如果存在两片形状相同的雪花,则输出:

Twin snowflakes found.

数据范围

1≤n≤100000,
0≤ai,j<10000000

输入样例:
2
1 2 3 4 5 6
4 3 2 1 6 5
输出样例:
Twin snowflakes found.

题意:

给 出 n 个 长 度 位 6 的 序 列 , 需 要 判 断 其 中 是 否 存 在 两 个 序 列 “ 相 似 ” 。 相 似 是 指 从 一 个 序 列 中 的 某 个 位 置 开 始 , 顺 时 针 或 逆 时 针 遍 历 该 序 列 , 得 到 的 结 果 与 另 一 序 列 相 同 。 给出n个长度位6的序列,需要判断其中是否存在两个序列“相似”。\\相似是指从一个序列中的某个位置开始,顺时针或逆时针遍历该序列,得到的结果与另一序列相同。 n6

EG:
样 例 : 4   3   2   1   6   5 , 从 1 开 始 “ 逆 时 针 ” 遍 历 即 可 得 到 : 1   2   3   4   5   6 , 因 此 这 两 个 序 列 相 似 。 样例:4 \ 3 \ 2 \ 1 \ 6 \ 5,从1开始“逆时针”遍历即可得到:1 \ 2 \ 3\ 4 \ 5 \ 6,因此这两个序列相似。 4 3 2 1 6 511 2 3 4 5 6

题解:

暴 力 做 法 就 是 对 每 一 个 序 列 都 枚 举 剩 下 的 序 列 与 之 匹 配 , 时 间 复 杂 度 O ( n 2 ) 。 暴力做法就是对每一个序列都枚举剩下的序列与之匹配,时间复杂度O(n^2)。 O(n2)

考 虑 优 化 匹 配 的 过 程 , 对 每 一 个 序 列 可 以 利 用 哈 希 表 , 以 O ( 1 ) 的 时 间 查 询 是 否 存 在 哈 希 值 相 同 的 序 列 , 若 存 在 , 再 进 一 步 按 顺 时 针 或 逆 时 针 确 认 是 否 相 似 。 整 个 过 程 的 时 间 复 杂 度 是 O ( n ) 的 。 考虑优化匹配的过程,对每一个序列可以利用哈希表,以O(1)的时间查询是否存在哈希值相同的序列,\\若存在,再进一步按顺时针或逆时针确认是否相似。整个过程的时间复杂度是O(n)的。 O(1)O(n)

具体落实:
① 、 用 结 构 体 带 存 储 每 个 序 列 的 6 个 权 值 , 按 “ 顺 时 针 ” 、 “ 逆 时 针 ” 重 载 ′ = = ′ 。 ①、用结构体带存储每个序列的6个权值,按“顺时针”、“逆时针”重载'=='。 6==
② 、 输 入 时 对 每 一 个 序 列 求 哈 希 值 , 并 判 断 哈 希 表 中 是 否 存 在 哈 希 值 相 同 的 序 列 , 若 存 在 , 进 一 步 确 认 相 似 ; 若 不 存 在 , 将 其 加 入 哈 希 表 。 ②、输入时对每一个序列求哈希值,并判断哈希表中是否存在哈希值相同的序列,\\ \qquad若存在,进一步确认相似;若不存在,将其加入哈希表。

注意:

① 、 顺 时 针 与 逆 时 针 遍 历 的 具 体 代 码 落 实 要 熟 悉 。 ② 、 哈 希 求 值 时 , 取 模 的 值 应 当 取 的 适 当 的 小 , 且 是 质 数 , 提 高 运 行 效 率 , 因 为 也 开 不 了 太 大 的 数 组 。 ③ 、 使 用 a u t o 来 遍 历 v e c t o r 。 ①、顺时针与逆时针遍历的具体代码落实要熟悉。\\②、哈希求值时,取模的值应当取的适当的小,且是质数,提高运行效率,因为也开不了太大的数组。\\③、使用auto来遍历vector。 使autovector


代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#define ll long long
#define inf 0x7fffffff
using namespace std;
const int N=1e5+10;
const int mod=99991;
int n;
struct node
{
    int a[6];
    bool operator == (const node &t)const
    {
        for(int i=0;i<6;i++)
        {
            if((a[0]==t.a[i%6]   ///顺时针
               &&a[1]==t.a[(1+i)%6]
               &&a[2]==t.a[(2+i)%6]
               &&a[3]==t.a[(3+i)%6]
               &&a[4]==t.a[(4+i)%6]
               &&a[5]==t.a[(5+i)%6])||
               (a[0]==t.a[i]   ///逆时针
                &&a[1]==t.a[(i+5)%6]
                &&a[2]==t.a[(i+4)%6]
                &&a[3]==t.a[(i+3)%6]
                &&a[4]==t.a[(i+2)%6]
                &&a[5]==t.a[(i+1)%6])
               )
                return true;
        }
        return false;
    }
};

vector<node>h[mod];  ///hash表
node A[N];

int main()
{
    cin>>n;
    for(int i=0;i<n;i++)
    {
        int sum=0;
        for(int j=0;j<6;j++) {scanf("%d",&A[i].a[j]);sum+=A[i].a[j]*2;}
        sum%=mod;

        for(auto k:h[sum])
            if(k==A[i])
            {
                cout<<"Twin snowflakes found."<<endl;
                return 0;
            }
        h[sum].push_back(A[i]);
        /*for(auto k:h[sum])
            cout<<k.a[1]<<" ";*/
    }
    cout<<"No two snowflakes are alike."<<endl;

    return 0 ;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值