/*
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".