16哈理工新生赛 H 下雪啦 (哈希表)

题目链接:点击打开链接

下雪啦
Time Limit: 2500 MSMemory Limit: 32768 K
Total Submit: 184(32 users)Total Accepted: 33(10 users)Rating: Special Judge: No
Description

陈月亮最喜欢的季节就是冬天了,这不看着窗外飘起了雪花,陈月亮开心的跑出屋来看雪。但是迷迷糊糊的陈月亮不知道自己是在做梦还是真的下起了雪。突然她想起了一句话,在真实世界中是没有两片一样的雪花的。于是你的任务就是比较这场雪中的所有雪花,如果出现了两朵完全一致的雪花,则证明陈月亮是在梦中。

每朵雪花用六个整数表示,范围在(1 – 10000000)之间,表示雪花六个花瓣的长度,六个整数的先后出现顺序可能是顺时针顺序也可能是逆时针顺序,并且可能是从任意一个花瓣开始的。比如说对同一个花瓣,描述方法可能是1 2 3 4 5 6 或者 4 3 2 1 6 5

Input

第一行为一个整数T,表示有T组测试数据。

每组测试数据第一行为一个整数N(0 < N <= 100000),表示雪花的数目。

接下来n行每行六个整数,描述一朵雪花。

Output

如果没有相同的雪花,输出“No two snowflakes are alike.”,否则输出“Twin snowflakes found.”

Sample Input

1

2

1 2 3 4 5 6

4 3 2 1 6 5


Sample Output

Twin snowflakes found.

Source
2016级新生程序设计全国邀请赛

题解:对每两朵雪花进行hash,如果找到相同的雪花就不再进行之后的哈希操作。详细看代码。


AC代码:

#include<cstring>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
const int MAXN=100005;
const int MOD=99983; //hash函数,取余的数(我用的是素数),可以是其他数 
int snow[MAXN][6];  //存储雪花信息
vector<int>Hash[MOD];//向量实现哈希表的存储
bool isSame(int a, int b)
{
    for(int i=0;i<6;i++)
	{
        if(/*顺时针方向*/
            (snow[a][0] == snow[b][i] &&
            snow[a][1] == snow[b][(i+1)%6] &&
            snow[a][2] == snow[b][(i+2)%6] &&
            snow[a][3] == snow[b][(i+3)%6] &&
            snow[a][4] == snow[b][(i+4)%6] &&
            snow[a][5] == snow[b][(i+5)%6])
            || /*逆时针方向*/
            (snow[a][0] == snow[b][(i+5)%6] &&
            snow[a][1] == snow[b][(i+4)%6] &&
            snow[a][2] == snow[b][(i+3)%6] &&
            snow[a][3] == snow[b][(i+2)%6] &&
            snow[a][4] == snow[b][(i+1)%6] &&
            snow[a][5] == snow[b][(i+0)%6])
            )
			return true;
    } 
	return false;
}

int T,N,ok;
int t;
int key;
int main()
{
    scanf("%d",&T);
    while(T--)
	{
        ok=0;
        scanf("%d",&N);
        for(int i=0;i<MOD;i++)
		{
            Hash[i].clear();
        }
        for(int i=0;i<N;i++)
		{
            int tot=0;
            for(int j=0;j<6;j++)
			{
                scanf("%d",&t);
                tot+=t;  //雪花六个花瓣的和
                snow[i][j]=t;
            }
            key=tot%MOD;  //求出key
            Hash[key].push_back(i);
        }
        
        //判断在hash表中hash[key]存储的雪花是否与雪花i相同
        for(int i=0;i<MOD;i++)
		{
            if(ok)break;
            if(Hash[i].size()<2) continue;
            for(int j=0;j<Hash[i].size()-1;j++)
			{
                for(int k=j+1;k<Hash[i].size();k++)
				{
                    if(isSame(Hash[i][j],Hash[i][k]))
					{
                        ok=1;
						break;
                    }
                }
            }
        }
        if(ok)printf("Twin snowflakes found.\n");
        else printf("No two snowflakes are alike.\n");
    }
    return 0;
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值