POJ3349 哈希算法

 

问题分析

 n n<100000)个雪花中判断是否存在两片完全相同的雪花,每片雪花有6个角,每个角的长度限制为1000000

 雪花相等的条件为, 雪花6个角的长度按顺序相等(这个顺序即可以是顺时针的也可以是逆时针的)

 

 n个雪花中,查找两片是否相等的雪花,采用暴力解法其,各个元素逐个比较的话,则其时间复杂度为n的平方,由于n可能会很大提交时肯定超时,所以选择采用哈希方法来查找两个判断两个元素是否相等,

 算法流程:

 1    建立一个雪花的节点node,并且获取其6个角的长度,当拥有相同的hash值的雪花时,即产生冲突时,采用开放地址发,即用链表存放拥有相同哈希值的雪花节点,该链表的头节点存放在哈希数组中

2   判断拥有哈希值的雪花是否相等。

 

 

ExpandedBlockStart.gif 代码
/*
   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 ;

}

 

 

转载于:https://www.cnblogs.com/smile2you/archive/2010/01/26/1656905.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值