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\n",a_cnt); 55 for(int i=0;i<a_cnt;i++) 56 printf(i==0?"%d":" %d",a[i]); 57 printf("\n"); 58 } 59 return 0; 60 }
这个题是刚刚自己敲过的,太激动了,啊啊啊啊啊
题意:给出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\n",ans/2); 88 } 89 return 0; 90 }
思路把前面的算出来放进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 }
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 }
加了一点优化,不过还跑到了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.\n"); 92 else 93 printf("No two snowflakes are alike.\n"); 94 } 95 return 0; 96 }
//未完