openjudge 两道hash题目

/*
 1 /*
 2 关键是两点可以确定一个正放心的另外两点
 3 主要得发现一个规律:当两点确认以后,正方形的位置其实就确认了(不过有两个)
 4 (这边的两个点是指正方形的一条边的两个点)
 5 所以枚举两个点o(n^2)然后就可以得出另外两个点的位置为(两种情况):
 6 s1:=b[i]-b[j]; s2:=c[i]-c[j];
 7 v1:=b[i]+s2; v2:=c[i]+(0-s1); v3:=b[j]+s2; v4:=c[j]+(0-s1);
 8 其中 v1 v2v3v4即为另外两个点的位置 还有另外一种为:
 9 v1:=b[i]+(0-s2); v2:=c[i]+s1; v3:=b[j]+(0-s2); v4:=c[j]+s1;
10 然后把二维转换为一维,为了避免负数,我把v1v2v3v4都加了20003,反正不影响结果
11 还有一点,由于正方形有四条边,我每条边都只做一遍,
12 //那么每个正方形都会算四次
13 //最后答案再除以四即可。 
14 */
15 #include<cstdio>
16 #include<iostream>
17 #include<algorithm>
18 #include<cstring>
19 using namespace std;
20 
21 struct H
22 {
23 int x,y;
24 }a[20000+1];
25 
26 int num[2000+1];
27 bool b[2001+1][2001+1];
28 int hash[20001*2+1];
29 bool cmp(H a,H b){return a.x<b.x;}
30 
31 int main()
32 {
33 int n;cin>>n;
34 while(n)
35 {
36 memset(b,false,sizeof(b));
37 memset(hash,0,sizeof(hash));
38 
39 int tot=0;
40 for(int i=1;i<=n;i++) 
41 scanf("%d %d",&a[i].x,&a[i].y),a[i].x+=20001,a[i].y+=20001,num[++tot]=a[i].x,num[++tot]=a[i].y;
42 
43 sort(num+1,num+1+tot);
44 for(int i=1;i<=tot;i++)
45 if(num[i]!=num[i-1]) 
46 hash[num[i]]=hash[num[i-1]]+1;//每个点给个编号hash 
47 
48 for(int i=1;i<=n;i++) 
49 b[hash[a[i].x]][hash[a[i].y]]=true;//有这个点 
50 
51 int ans=0;
52 sort(a+1,a+n+1,cmp);//横坐标排序 
53 for(int i=1;i<=n;i++)//列举每条边 
54 for(int j=1;j<=n;j++)
55 if(i!=j)
56 if(a[i].x<a[j].x&&a[i].y<=a[j].y)
57 if(a[j].y-a[j].x+a[i].x>=0&&a[i].y-a[j].x+a[i].x>=0)
58 if
59 (
60 b[ hash[a[j].x+a[j].y-a[i].y] ][ hash[a[j].y-a[j].x+a[i].x] ]
61 &&
62 b[ hash[a[i].x+a[j].y-a[i].y] ][ hash[a[i].y-a[j].x+a[i].x] ]
63 ) ans++;
64 
65 printf("%d\n",ans);
66 scanf("%d",&n);
67 }
68 return 0;
69 }

给出平面上一些点的坐标,统计由这些点可以组成多少个正方形。注意:正方形的边不一定平行于坐标轴。

 

 

 1 #include<cstdio>
 2 #include<cstring>
 3 const int hs=1333331;//why!
 4 struct node
 5 {
 6 long long x,y,w;
 7 int nex;
 8 }l[1005*1005];
 9 int h[hs],cnt;
10 long long s[1005];
11 long long ans;
12 int n;
13 int i,a,b,c,d;
14 int p,he,cha;
15 int hash(long long x)//!!!!!!!!!!!!!!!!
16 {
17 return ((x%hs)+hs)%hs;
18 }
19 int main()
20 {
21 while(scanf("%d",&n)==1)
22 {
23 if(n==0)break;
24 for(i=1;i<=n;i++)
25 scanf("%lld",&s[i]);
26 memset(h,0,sizeof(h));
27 cnt=0;
28 for(a=1;a<=n;a++)
29 for(b=a+1;b<=n;b++)
30 {
31 cnt++;
32 he=hash(s[a]+s[b]);
33 l[cnt].x=a;
34 l[cnt].y=b;
35 l[cnt].w=s[a]+s[b];
36 l[cnt].nex=h[he];
37 h[he]=cnt;
38 }
39 ans=-536870913;
40 for(c=1;c<=n;c++)
41 for(d=1;d<=n;d++)
42 {
43 if(d==c)continue;
44 cha=hash(s[d]-s[c]);
45 for(p=h[cha];p!=0;p=l[p].nex)
46 {
47 if(l[p].w!=s[d]-s[c])continue;
48 if(l[p].x!=c&&l[p].x!=d&&l[p].y!=c&&l[p].y!=d&&s[d]>ans)
49 ans=s[d];
50 }
51 }
52 if(ans==-536870913)printf("no solution\n");
53 else printf("%lld\n",ans);
54 }
55 return 0;
56 }

Given S, a set of integers, find the largest d such that a + b + c = d where a, b, c, and d are distinct elements of S.输入Several S, each consisting of a line containing an integer 1 <= n <= 1000 indicating the number of elements in S, followed by the elements of S, one per line. Each element of S is a distinct integer between -536870912 and +536870911 inclusive. The last line of input contains 0.输出For each S, a single line containing d, or a single line containing "no solution".

转载于:https://www.cnblogs.com/babyyang/p/5327694.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值