hash题目大汇总

hlg1287数字去重和排序II--最基础拉链式hash

模板代码:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int maxn=1007;
 8 
 9 struct Node
10 {
11     int d;
12     Node*next;
13 };
14 
15 Node *Point[maxn+1];
16 Node num[maxn+1];
17 int a[10000+1];
18 
19 int a_cnt;
20 int n_cnt;
21 
22 int main()
23 {
24     int n,x;
25     while(scanf("%d",&n)!=EOF)
26     {
27         memset(Point,0,sizeof(Point));
28         a_cnt=n_cnt=0;
29         while(n--)
30         {
31             scanf("%d",&x);
32             int p=x%maxn;
33             Node*pt=Point[p];
34             bool found=false;
35             while(pt)
36             {
37                 if(pt->d==x)
38                 {
39                     found=true;
40                     break;
41                 }
42                 pt=pt->next;
43             }
44             if(!found)
45             {
46                 num[n_cnt].d=x;
47                 num[n_cnt].next=Point[p];
48                 Point[p]=&num[n_cnt];
49                 n_cnt++;
50                 a[a_cnt++]=x;
51             }
52         }
53         sort(a,a+a_cnt);
54         printf("%d
",a_cnt);
55         for(int i=0;i<a_cnt;i++)
56         printf(i==0?"%d":" %d",a[i]);
57         printf("
");
58     }
59     return 0;
60 }
View Code

poj2002  Squares  点的hash

这个题是刚刚自己敲过的,太激动了,啊啊啊啊啊

题意:给出n个点的坐标,问最多有多少个正方形。

思路:把所有的点都储存起来,一次枚举两个点,求出另外两个点 看是否已经出现过

代码:

 1 #include<iostream>
 2 #include<string.h>
 3 #include<stdio.h>
 4 #include<algorithm>
 5 #include<math.h>
 6 
 7 using namespace std;
 8 
 9 const int maxn=1007;
10 
11 struct Node
12 {
13     int x;
14     int y;
15     Node *next;
16 };
17 
18 bool cmp(Node N1,Node N2)
19 {
20     if(N1.x!=N2.x)
21     return N1.x<N2.x;
22     else
23     return N1.y<N2.y;
24 }
25 
26 Node*point[maxn+1];
27 Node num[maxn+1];
28 
29 bool find(int a,int b)
30 {
31     int p=abs(a+b)%maxn;
32     Node*pt=point[p];//p位置的最新指针
33     while(pt)//最后一个为空指针
34     {
35         if(pt->x==a&&pt->y==b)
36         {
37             return true;//找到一个点的横纵坐标符合要求
38         }
39         pt=pt->next;//指向下一个指针
40     }
41     return false;//未找到
42 }
43 
44 int main()
45 {
46     int n;
47     //freopen("aa.txt","r",stdin);
48     while(scanf("%d",&n)!=EOF)
49     {
50         if(n==0)
51         break;
52         for(int i=0;i<n;i++)
53             scanf("%d%d",&num[i].x,&num[i].y);
54         sort(num,num+n,cmp);
55 
56         memset(point,0,sizeof(point));
57 
58         for(int i=0;i<n;i++)
59         {
60             int p=abs(num[i].x+num[i].y)%maxn;//为寻找point存储的最后插入该位置的指针
61             num[i].next=point[p];//另这个数(num[i])的指针指向该位置上一个指针的位置
62             //(因为point储存的是最近更新点的指针)
63             point[p]=&num[i];//更新point为最新的指针
64             /*整个过程不需要查找因为给的每个点都不相同*/
65         }
66 
67         int ans=0;
68         int x1,x2,x3,x4,y1,y2,y3,y4;
69         for(int i=0;i<n;i++)
70         {
71             for(int j=i+1;j<n;j++)
72             {
73                 x1=num[i].x;
74                 y1=num[i].y;
75                 x2=num[j].x;
76                 y2=num[j].y;
77 
78                 x3=x1+(y2-y1);
79                 y3=y1-(x2-x1);
80                 x4=x2+(y2-y1);
81                 y4=y2-(x2-x1);
82 
83                 if(find(x3,y3)&&find(x4,y4))
84                 ans++;
85             }
86         }
87         printf("%d
",ans/2);
88     }
89     return 0;
90 }
View Code

 poj 1840Eqs  数的hash

hlg1013Eqs

思路把前面的算出来放进hash表中在在后面查找

代码:

 1 #include<iostream>
 2 #include<string.h>
 3 #include<stdio.h>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 const int maxn=50007;
 8 struct Node
 9 {
10     int d;
11     Node*next;
12 };
13 
14 Node *point[maxn+1];
15 Node num[10005];
16 int numm[10005];
17 
18 int main()
19 {
20     int a1,a2,a3,a4,a5;
21     //freopen("aa.txt","r",stdin);
22     while(cin>>a1>>a2>>a3>>a4>>a5)
23     {
24         memset(point,0,sizeof(point));
25         memset(numm,0,sizeof(numm));
26         int n_cnt=0;
27         for(int i=-50;i<=50;i++)
28         {
29             if(i==0)
30             continue;
31             for(int j=-50;j<=50;j++)
32             {
33                 if(j==0)
34                 continue;
35                 int key=a1*i*i*i+a2*j*j*j;
36                 int p=abs(key)%maxn;
37                 num[n_cnt].d=key;
38                 num[n_cnt].next=point[p];
39                 point[p]=&num[n_cnt];
40                 n_cnt++;
41             }
42         }
43         int ans=0;
44         for(int i=-50;i<=50;i++)
45         {
46             if(i==0)
47             continue;
48             for(int j=-50;j<=50;j++)
49             {
50                 if(j==0)
51                 continue;
52                 for(int k=-50;k<=50;k++)
53                 {
54                     if(k==0)
55                     continue;
56 
57                     int key=a3*i*i*i+a4*j*j*j+a5*k*k*k;
58 
59                     int p=abs(key)%maxn;
60 
61                     Node*pt=point[p];
62 
63                     while(pt)
64                     {
65                         if(pt->d==key)
66                         {
67                             ans++;
68                         }
69                         pt=pt->next;
70                     }
71                 }
72             }
73         }
74         cout<<ans<<endl;
75     }
76     return 0;
77 }
View Code

 poj3349Snowflake Snow Snowflakes

加了一步查询操作,卡了一晚上终于险过,代码仍需要优化

代码:

 1 #include<iostream>
 2 #include<string.h>
 3 #include<stdio.h>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn=10007;
 7 
 8 struct Node
 9 {
10     long long int aa[7];
11     Node*next;
12 };
13 
14 Node *point[maxn+1];
15 Node num[100005];
16 
17 bool judge(long long int a[6],long long int  b[6]){//一共六个元素,就这样好了。。。囧。。。
18     if (a[0]==b[0]&&a[1]==b[1]&&a[2]==b[2]&&a[3]==b[3]&&a[4]==b[4]&&a[5]==b[5])      return 1;
19     else if(a[0]==b[1]&&a[1]==b[2]&&a[2]==b[3]&&a[3]==b[4]&&a[4]==b[5]&&a[5]==b[0])  return 1;
20     else if(a[0]==b[2]&&a[1]==b[3]&&a[2]==b[4]&&a[3]==b[5]&&a[4]==b[0]&&a[5]==b[1])  return 1;
21     else if(a[0]==b[3]&&a[1]==b[4]&&a[2]==b[5]&&a[3]==b[0]&&a[4]==b[1]&&a[5]==b[2])  return 1;
22     else if(a[0]==b[4]&&a[1]==b[5]&&a[2]==b[0]&&a[3]==b[1]&&a[4]==b[2]&&a[5]==b[3])  return 1;
23     else if(a[0]==b[5]&&a[1]==b[0]&&a[2]==b[1]&&a[3]==b[2]&&a[4]==b[3]&&a[5]==b[4])  return 1;
24     else return 0;
25 }
26 
27 bool judge2(long long int a[6],long long int  b[6]){//一共六个元素,就这样好了。。。囧。。。
28     if(a[0]==b[0]&&a[1]==b[5]&&a[2]==b[4]&&a[3]==b[3]&&a[4]==b[2]&&a[5]==b[1])      return 1;
29     else if(a[0]==b[1]&&a[1]==b[0]&&a[2]==b[5]&&a[3]==b[4]&&a[4]==b[3]&&a[5]==b[2])  return 1;
30     else if(a[0]==b[2]&&a[1]==b[1]&&a[2]==b[0]&&a[3]==b[5]&&a[4]==b[4]&&a[5]==b[3])  return 1;
31     else if(a[0]==b[3]&&a[1]==b[2]&&a[2]==b[1]&&a[3]==b[0]&&a[4]==b[5]&&a[5]==b[4])  return 1;
32     else if(a[0]==b[4]&&a[1]==b[3]&&a[2]==b[2]&&a[3]==b[1]&&a[4]==b[0]&&a[5]==b[5])  return 1;
33     else if(a[0]==b[5]&&a[1]==b[4]&&a[2]==b[3]&&a[3]==b[2]&&a[4]==b[1]&&a[5]==b[0])  return 1;
34     else return 0;
35 }
36 
37 
38 int main()
39 {
40     long long int n,xx[7];
41     //freopen("aa.txt","r",stdin);
42     while(scanf("%lld",&n)!=EOF)
43     {
44         memset(point,0,sizeof(point));
45         long long int n_cnt=0;
46         bool ans=false;
47         while(n--)
48         {
49             long long int sum=0;
50             for(int i=0;i<6;i++)
51             {
52                 scanf("%lld",&xx[i]);
53                 sum+=xx[i];
54             }
55             long long int p=sum%maxn;
56             Node*pt=point[p];
57             bool found=false;
58             while(pt)
59             {
60                 if(judge(pt->aa,xx)||judge2(pt->aa,xx))
61                 {
62                     found=true;
63                     ans=true;
64                     break;
65                 }
66                 pt=pt->next;
67             }
68             if(!found){
69             for(int i=0;i<6;i++)
70             {
71                 num[n_cnt].aa[i]=xx[i];
72             }
73             num[n_cnt].next=point[p];
74             point[p]=&num[n_cnt];
75             n_cnt++;
76             }
77         }
78         if(ans)
79         cout<<"Twin snowflakes found."<<endl;
80         else
81         cout<<"No two snowflakes are alike."<<endl;
82     }
83     return 0;
84 }
View Code

 加了一点优化,不过还跑到了2000+  

 1 #include<iostream>
 2 #include<string.h>
 3 #include<stdio.h>
 4 #include<set>
 5 #include<vector>
 6 #include<map>
 7 #include<algorithm>
 8 #include<iomanip>
 9 #include<queue>
10 #include<stack>
11 #include<math.h>
12 #include<time.h>
13 #include<stdlib.h>
14 
15 const int maxn=1000007;
16 
17 struct Node
18 {
19     int a[7];
20     Node *next;
21 };
22 
23 Node *point[maxn+1];
24 Node num[100005];
25 
26 bool check(int *a1,int *b1)
27 {
28     bool flag=false;
29     for(int i=0;i<6;i++)
30     {
31         if(a1[0]==b1[i])
32         {
33             int x1=i%6,x2=(i+1)%6,x3=(i+2)%6,x4=(i+3)%6,x5=(i+4)%6,x6=(i+5)%6;
34             int y1=(i+6)%6,y2=(i+5)%6,y3=(i+4)%6,y4=(i+3)%6,y5=(i+2)%6,y6=(i+1)%6;
35             if(a1[0]==b1[x1]&&a1[1]==b1[x2]&&a1[2]==b1[x3]&&a1[3]==b1[x4]&&a1[4]==b1[x5]&&a1[5]==b1[x6])
36             {
37                 flag=true;
38                 break;
39             }
40             if(a1[0]==b1[y1]&&a1[1]==b1[y2]&&a1[2]==b1[y3]&&a1[3]==b1[y4]&&a1[4]==b1[y5]&&a1[5]==b1[y6])
41             {
42                 flag=true;
43                 break;
44             }
45         }
46     }
47     return flag;
48 }
49 
50 int main()
51 {
52     int n;
53     int x[7];
54     //freopen("aa.txt","r",stdin);
55     while(scanf("%d",&n)!=EOF)
56     {
57         memset(point,0,sizeof(point));
58         bool found=false;
59         int n_cnt=0;
60         while(n--)
61         {
62             int sum=0;
63             for(int i=0;i<6;i++){
64                 scanf("%d",&x[i]);
65                 sum+=x[i];
66             }
67             int p=sum%maxn;
68 
69             Node *pt=point[p];
70 
71             while(pt)
72             {
73                 if(check(pt->a,x))
74                 {
75                     found=true;
76                     break;
77                 }
78                 pt=pt->next;
79             }
80 
81             if(!found)
82             {
83                 for(int i=0;i<6;i++)
84                 num[n_cnt].a[i]=x[i];
85                 num[n_cnt].next=point[p];
86                 point[p]=&num[n_cnt];
87                 n_cnt++;
88             }
89         }
90         if(found)
91         printf("Twin snowflakes found.
");
92         else
93         printf("No two snowflakes are alike.
");
94     }
95     return 0;
96 }
View Code

 //未完

原文地址:https://www.cnblogs.com/zhanzhao/p/3593108.html