POJ3349 哈希算法
问题分析
在n (n<100000)个雪花中判断是否存在两片完全相同的雪花,每片雪花有6个角,每个角的长度限制为1000000
雪花相等的条件为, 雪花6个角的长度按顺序相等(这个顺序即可以是顺时针的也可以是逆时针的)
在n个雪花中,查找两片是否相等的雪花,采用暴力解法其,各个元素逐个比较的话,则其时间复杂度为n的平方,由于n可能会很大提交时肯定超时,所以选择采用哈希方法来查找两个判断两个元素是否相等,
算法流程:
1 建立一个雪花的节点node,并且获取其6个角的长度,当拥有相同的hash值的雪花时,即产生冲突时,采用开放地址发,即用链表存放拥有相同哈希值的雪花节点,该链表的头节点存放在哈希数组中
2 判断拥有哈希值的雪花是否相等。
代码
/*
poj 3349
哈希算法
用G++编译提交通过,但用C++编译提交时会超时
*/
#include<iostream>
#include <algorithm>
#include <cstdio>
const long maxn=100000;
const long mtemp=100000;
/*
每片雪花的具体长度,并且是一个链表
*/
typedef struct node
{
long data[6];
node *next;
}node;
/*
存放雪花的初始地址
*/
typedef struct hnode
{
int elCount;
node *head;
}HeadNode;
/*
全局变量
*/
HeadNode *snows=new HeadNode[maxn];
/*
比较两片雪花是否相等
*/
bool CompareArray( long *d1, long *d2,const long len)
{
int i,j,count,t;
bool flag=false;
count=0;
/*
从数组的头开始判断两个数组是否相等,即两片雪花是否相等
依次以d1数组的第 i(0<=i>=5)个元素作为头依次和d2数组的元素作比较,
只有各个元素都相等时才证明两片雪花相等。
*/
while(count<len)
{
i=count;
for(j=0;j<len;j++)
{
if(d1[i]==d2[j])
{
i++;
if(i>=len)i=0;
}else
{
break;
}
}
if(j>=len)
{
flag=true;
}
if(flag==true)break;
count++;
}
/*
从数组的末尾开始判断两个数组是否相等
*/
if(flag==false)
{
count=len-1;
while(count>=0)
{
i=count;
for(j=0;j<len;j++)
{
if(d1[i]==d2[j])
{
i--;
if(i<0)i=len-1;
}else
{
break;
}
}
if(j>=len)
{
flag=true;
}
if(flag==true)break;
count--;
}
}
return flag;
}
int main(void)
{
long n,c,k,key,index;
int i,j;
long *a;
bool isHasSameSnowFlake;
node *t,*headtemp;
std::cin>>n;
c=getchar();
isHasSameSnowFlake=false;
for(i=0;i<n;i++)
{
//a=new long[6];
t=new node();
t->next=NULL;
key=0;
for(j=0;j<6;j++)
{
k=0;
c='0';
while(c!='\n'&&c!=' ')
{
k=k*10+c-'0';
c=getchar();
}
t->data[j]=k;
key+=k;
}
//qsort(a,6,sizeof(long),Compare);
if(isHasSameSnowFlake==false)
{
index=key%mtemp; //取当前输入的雪花的hash值,通过求6个角的长度的和,然后对mtemp相除取余数,即为其hash值
if(snows[index].elCount>0) //判断已经输入的雪花中是否已经存在拥有相同hash值的雪花
{
headtemp=snows[index].head->next;
while(headtemp!=NULL)
{ //判断拥有相同hash值的雪花是否是两片相同的雪花
isHasSameSnowFlake=CompareArray(headtemp->data,t->data,6);
if(isHasSameSnowFlake==true) break;
headtemp=headtemp->next;
}
if(isHasSameSnowFlake==false)
{
t->next=snows[index].head->next;
snows[index].head->next=t;
snows[index].elCount++;
}
/*t->next=snows[index].head->next;
snows[index].head->next=t;*/
}else
{
snows[index].elCount++;
snows[index].head=new node();
snows[index].head->next=t;
}
}
}
if(isHasSameSnowFlake==false){
std::cout<<"No two snowflakes are alike."<<std::endl;
}else{
std::cout<<"Twin snowflakes found."<<std::endl;
}
return 0;
}
poj 3349
哈希算法
用G++编译提交通过,但用C++编译提交时会超时
*/
#include<iostream>
#include <algorithm>
#include <cstdio>
const long maxn=100000;
const long mtemp=100000;
/*
每片雪花的具体长度,并且是一个链表
*/
typedef struct node
{
long data[6];
node *next;
}node;
/*
存放雪花的初始地址
*/
typedef struct hnode
{
int elCount;
node *head;
}HeadNode;
/*
全局变量
*/
HeadNode *snows=new HeadNode[maxn];
/*
比较两片雪花是否相等
*/
bool CompareArray( long *d1, long *d2,const long len)
{
int i,j,count,t;
bool flag=false;
count=0;
/*
从数组的头开始判断两个数组是否相等,即两片雪花是否相等
依次以d1数组的第 i(0<=i>=5)个元素作为头依次和d2数组的元素作比较,
只有各个元素都相等时才证明两片雪花相等。
*/
while(count<len)
{
i=count;
for(j=0;j<len;j++)
{
if(d1[i]==d2[j])
{
i++;
if(i>=len)i=0;
}else
{
break;
}
}
if(j>=len)
{
flag=true;
}
if(flag==true)break;
count++;
}
/*
从数组的末尾开始判断两个数组是否相等
*/
if(flag==false)
{
count=len-1;
while(count>=0)
{
i=count;
for(j=0;j<len;j++)
{
if(d1[i]==d2[j])
{
i--;
if(i<0)i=len-1;
}else
{
break;
}
}
if(j>=len)
{
flag=true;
}
if(flag==true)break;
count--;
}
}
return flag;
}
int main(void)
{
long n,c,k,key,index;
int i,j;
long *a;
bool isHasSameSnowFlake;
node *t,*headtemp;
std::cin>>n;
c=getchar();
isHasSameSnowFlake=false;
for(i=0;i<n;i++)
{
//a=new long[6];
t=new node();
t->next=NULL;
key=0;
for(j=0;j<6;j++)
{
k=0;
c='0';
while(c!='\n'&&c!=' ')
{
k=k*10+c-'0';
c=getchar();
}
t->data[j]=k;
key+=k;
}
//qsort(a,6,sizeof(long),Compare);
if(isHasSameSnowFlake==false)
{
index=key%mtemp; //取当前输入的雪花的hash值,通过求6个角的长度的和,然后对mtemp相除取余数,即为其hash值
if(snows[index].elCount>0) //判断已经输入的雪花中是否已经存在拥有相同hash值的雪花
{
headtemp=snows[index].head->next;
while(headtemp!=NULL)
{ //判断拥有相同hash值的雪花是否是两片相同的雪花
isHasSameSnowFlake=CompareArray(headtemp->data,t->data,6);
if(isHasSameSnowFlake==true) break;
headtemp=headtemp->next;
}
if(isHasSameSnowFlake==false)
{
t->next=snows[index].head->next;
snows[index].head->next=t;
snows[index].elCount++;
}
/*t->next=snows[index].head->next;
snows[index].head->next=t;*/
}else
{
snows[index].elCount++;
snows[index].head=new node();
snows[index].head->next=t;
}
}
}
if(isHasSameSnowFlake==false){
std::cout<<"No two snowflakes are alike."<<std::endl;
}else{
std::cout<<"Twin snowflakes found."<<std::endl;
}
return 0;
}