POJ 3349.Snowflake Snow Snowflakes

版权声明:本文为博主原创文章,记录蒟蒻的成长之路,欢迎吐槽~ https://blog.csdn.net/PegasiTIO/article/details/89385117

描述

You may have heard that no two snowflakes are alike. Your task is to write a program to determine whether this is really true. Your program will read information about a collection of snowflakes, and search for a pair that may be identical. Each snowflake has six arms. For each snowflake, your program will be provided with a measurement of the length of each of the six arms. Any pair of snowflakes which have the same lengths of corresponding arms should be flagged by your program as possibly identical.

输入

The first line of input will contain a single integer n, 0 < n ≤ 100000, the number of snowflakes to follow. This will be followed by n lines, each describing a snowflake. Each snowflake will be described by a line containing six integers (each integer is at least 0 and less than 10000000), the lengths of the arms of the snow ake. The lengths of the arms will be given in order around the snowflake (either clockwise or counterclockwise), but they may begin with any of the six arms. For example, the same snowflake could be described as 1 2 3 4 5 6 or 4 3 2 1 6 5.

输出

If all of the snowflakes are distinct, your program should print the message: No two snowflakes are alike. If there is a pair of possibly identical snow akes, your program should print the message: Twin snowflakes found.

样例输入

2 1 2 3 4 5 6 4 3 2 1 6 5

样例输出

Twin snowflakes found.


哈希表

哈希值计算公式:每个点值相加为sum,每个相乘为mulhash = (sum + mul) % PP取较大的质数

每次插入雪花时判断是否有相同的雪花,有相同返回真程序结束,没有返回假继续输入

用邻接表解决哈希冲突

#include <cstring>
#include <iostream>
using namespace std;
static const auto io_sync_off = []() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    return nullptr;
}();

using ll = long long;
const int maxn = 100005;
int n, tot, P = 99991;//防止超过数组最大值
int snow[maxn][6], Next[maxn], head[maxn];
//保存雪花的长度信息,指向邻接表下一个元素,邻接表表头

int h(int *a)
{
    //计算哈希值
    int sum = 0, mul = 1;
    for (int i = 0; i < 6; ++i)
    {
        sum = (sum + a[i]) % P;
        mul = (ll)mul * a[i] % P;
    }
    return (sum + mul) % P;
}

bool check(int *a, int *b)
{
    //判断顺时针或者逆时针下是否相同,相同就是同一片雪花
    for (int i = 0; i < 6; ++i)//从a雪花第一个位置开始
        for (int j = 0; j < 6; ++j)//从b雪花第一个位置开始
        {
            bool equ = 1;
            for (int k = 0; k < 6; ++k) //顺时针查找
                if (a[(i + k) % 6] != b[(j + k) % 6])
                {
                    equ = 0;
                    break;
                }
            if (equ)
                return true;
            equ = 1;
            for (int k = 0; k < 6; ++k) //逆时针查找
                if (a[(i + k) % 6] != b[(j - k + 6) % 6])
                {
                    equ = 0;
                    break;
                }
            if (equ)
                return true;
        }
    return false;
}

bool insert(int *a)
{
    int hash = h(a);//计算当前雪花的哈希值
    //遍历该哈希值类别下的邻接表,也就是和当前雪花哈希值相同的所有雪花
    for (int i = head[hash]; i; i = Next[i])
        if (check(a, snow[i]))
            return true;

    //未找到,插入雪花
    ++tot;
    memcpy(snow[tot], a, 6 * sizeof(int)); //保存雪花信息到第tot个
    Next[tot] = head[hash];                //当前雪花的下一个指向该hash类别表头的位置
    head[hash] = tot;                      //当前雪花的保存位置
    return false;
}

int main()
{
    cin >> n;
    // bool flag = 0;
    for (int i = 0; i < n; ++i)
    {
        int a[6];
        for (int j = 0; j < 6; ++j)
            cin >> a[j];
        /* if (flag)
            continue */;
        if (insert(a))
            // flag = 1;
        {
            printf("Twin snowflakes found.\n");
            return 0;//poj这不return 0;会超时
        }
    }
    printf("No two snowflakes are alike.\n");
    // printf("%s\n", flag ? "Twin snowflakes found." : "No two snowflakes are alike.");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/PegasiTIO/article/details/89385117
今日推荐