poj3349-hash

来源:互联网 发布:统计学的数据分析实例 编辑:程序博客网 时间:2024/05/21 19:22

题目连接

分析:

对于一个六边形,长度个不一个样,而物体可以旋转,这是一个很头痛的问题,该如何辨别这些相同的六边形,链表?这显然不好,用map行不通,想想看,

比如:1 2 3 4 5 6和1 2 2 3 4 5,他们的和是不同的,所以我们直接就可以否定他们相同,但对于 1 2 3 4 5 6和 1 3 2 4 6 5,他们的和是相同的,但属于不同的

六边形,这些数据有些好辨别,有些不好辨别,我们应该让他们离散化,尽可能的让他们离散,由于sum和可能很大,我们就mod一个数就是让他们离散化,

对于余数相同的,我们就hash吧!。

hash思想:对于很多数据,存在个体差别和个体相同,要查找一个数据,很不容易,我们就先把它们离散化,离散化并不能消除个体相同的,但在很大程度上

降低了查找数据的难度,对于转化后的数据,还是相同,我们就把它放在一起(即放在同一行)。这样我就根据该行,一次找下去,就可以了。说白了,hash思想的

精粹就是:类比思想。一大批数据,我们只要对这些数在一个特定的M(方式),在M的处理下,每个数据有个映射,沿着这条路径,可以彼此建立联系,把原问题转化成

另一个问题,大大降低难度了。

好好体会这种思想!

本题代码如下:

#include<stdio.h>#include<string.h>#define H 1000000#define N 2000000struct node{       int date[6];       int next;}Node[N];int hashtable[N],cnt=0;int get_hash(int *num){    int sum=0;    for(int i=0;i<6;i++)     sum=(sum+num[i])%H;     return sum;              }bool cmp(int *num1,int *num2){     for(int i=0;i<6;i++){         if(num1[i]!=num2[i])              return false;     }     return true;}void insert (int *num,int x){     for(int i=0;i<6;i++){      Node[cnt].date[i]=num[i];     }     Node[cnt].next=hashtable[x];     hashtable[x]=cnt++;}bool search(int *num){      int r=get_hash(num);      int m=hashtable[r];      while(m!=-1){       if(cmp(num,Node[m].date)) return true;        m=Node[m].next;                     }     insert(num,r); return false;}int main(){    int num[2][12],t,i,flag=0;    memset(hashtable,-1,sizeof(hashtable));    scanf("%d",&t);    while(t--){       for(i=0;i<6;i++){          scanf("%d",&num[0][i]);          num[0][6+i]=num[0][i];   //构造循环        }         for(i=0;i<6;i++){         num[1][i+6]=num[1][i]=num[0][5-i];   //构造反循环 ,巧妙之处。        }         for(i=0;i<6;i++){        if(search(num[0]+i)||search(num[1]+i))        {          flag=1;          break;        }       }  }       if(flag) printf("Twin snowflakes found.\n");       else printf("No two snowflakes are alike.\n");           return 0;}


原创粉丝点击