pku 2002
2009年7月18日 星期六
题目链接:PKU 2002 Squares
分类:哈希
题目分析与算法原型
其实该题和1971很像(还有3432题除了输入的点的范围其他的基本和这题一模一样)区别在于这题是统计正方形个数,而那题是统计平行四边形个数,个人感觉这题稍微复杂一些,因为正方形属于平行四边形,我用那题的思路,将那题的代码改了一下,即在平行四边形的基础上判断是否是正方形,结果TLE了,只能另找方法了。
算法1:其实可以发现一点,就是如果给你一个正方形的两个对角线点的坐标,则根据正方形的特点,一定可以算出另外的两点的坐标,利用这一点,这道题目基本就可以hash了,具体做法是,先将读入的n个点的坐标按照其x坐标作为关键值进行hash,然后像1971一样枚举每两个不同的点,将他们作为某个正方形的对角线,算出两外的两个点,然后对于新算出的两个点的x坐标进行hash查找,对于x相同的点,判断y是否也相同,若相同,则继续hash另一个点的坐标,若两次都能找到则正方形个数加1。在哈希判断时若找到相同的则直接退出本次查找,否则一直查找到链表的末尾,表示没有以该两点作为对角线的正方形。
算法2:这道题目还可以不用哈希,直接用二分来查找,同算法一,也是先枚举每两个点,根据公式算出另外的两个点,不过,直接用二分来查找这两个点是否存在,当然了,事先需要对输入的坐标排个序,先按x坐标从小到大排序,相同的x的点以y坐标从小到大排序,二分检测时候,先找到与当前被检索的点的x坐标相同的所有点的下标范围,然后再次在这个范围里面再次二分查找是否存在与其y坐标相同的点.........
需要注意的是这种方法,对于同一个正方形来说,因为与两条对角线,所以会算了两次,所以最后输出的时候需要除以2,呵呵
Code1:
1 #include < stdio.h >
2 #include < math.h >
3 #include < string .h >
4 #define max 1005
5 #define pianyi 20005
6 #define prime 39997
7 #define len 50000
8 int n,i,j,start,sum,count,pos[max][ 2 ];
9 double x[ 3 ],y[ 3 ];
10
11 struct node
12 {
13 int px,py;
14 int next;
15} hash[len];
16
17 void cal( int a, int b)
18 {
19 double x0=(double)(pos[a][0]+pos[b][0])/2,y0=(double)(pos[a][1]+pos[b][1])/2;
20 if((pos[b][1]-pos[a][1])*(pos[b][0]-pos[a][0])>0)
21 {
22 x[1]=x0-fabs(pos[b][1]-pos[a][1])/2;
23 x[2]=x0+fabs(pos[b][1]-pos[a][1])/2;
24 y[1]=y0+fabs(pos[b][0]-pos[a][0])/2;
25 y[2]=y0-fabs(pos[b][0]-pos[a][0])/2;
26 }
27 else
28 {
29 x[1]=x0-fabs(pos[b][1]-pos[a][1])/2;
30 x[2]=x0+fabs(pos[b][1]-pos[a][1])/2;
31 y[1]=y0-fabs(pos[b][0]-pos[a][0])/2;
32 y[2]=y0+fabs(pos[b][0]-pos[a][0])/2;
33 }
34}
35 int Hash2( int x, int y)
36 {
37 int now=x%prime;
38 while(hash[now].next!=-1)
39 {
40 if(hash[hash[now].next].py==y)return 1;
41 now=hash[now].next;
42 }
43 return 0;
44}
45 void Hash( int k)
46 {
47 int now=k%prime;
48 while(hash[now].next!=-1)now=hash[now].next;
49 hash[start].next=-1;
50 hash[now].next=start;
51 start++;
52}
53 int main()
54 {
55 while(scanf("%d",&n)!=EOF&&n)
56 {
57 start=prime+10;
58 memset(hash,-1,sizeof(hash));
59 for(i=0;i<n;i++)
60 {
61 scanf("%d%d",&pos[i][0],&pos[i][1]);
62 hash[start].px=pos[i][0];
63 hash[start].py=pos[i][1];
64 Hash(pos[i][0]+pianyi);
65 }
66 count=0;
67 for(i=0;i<n-1;i++)
68 for(j=i+1;j<n;j++)
69 {
70 int res1,res2;
71 cal(i,j);
72 int t1=(int)x[1],t2=(int)x[2],t3=(int)y[1],t4=(int)y[2];
73 if(t1!=x[1]||t2!=x[2]||t3!=y[1]||t4!=y[2])continue;
74 res1=Hash2((int)x[1]+pianyi,(int)y[1]);
75 res2=Hash2((int)x[2]+pianyi,(int)y[2]);
76 if(res1&&res2)count++;
77 }
78 printf("%d\n",count/2);
79 }
80 return 0;
81}
82
83
题目链接:PKU 2002 Squares
分类:哈希
题目分析与算法原型
其实该题和1971很像(还有3432题除了输入的点的范围其他的基本和这题一模一样)区别在于这题是统计正方形个数,而那题是统计平行四边形个数,个人感觉这题稍微复杂一些,因为正方形属于平行四边形,我用那题的思路,将那题的代码改了一下,即在平行四边形的基础上判断是否是正方形,结果TLE了,只能另找方法了。
算法1:其实可以发现一点,就是如果给你一个正方形的两个对角线点的坐标,则根据正方形的特点,一定可以算出另外的两点的坐标,利用这一点,这道题目基本就可以hash了,具体做法是,先将读入的n个点的坐标按照其x坐标作为关键值进行hash,然后像1971一样枚举每两个不同的点,将他们作为某个正方形的对角线,算出两外的两个点,然后对于新算出的两个点的x坐标进行hash查找,对于x相同的点,判断y是否也相同,若相同,则继续hash另一个点的坐标,若两次都能找到则正方形个数加1。在哈希判断时若找到相同的则直接退出本次查找,否则一直查找到链表的末尾,表示没有以该两点作为对角线的正方形。
算法2:这道题目还可以不用哈希,直接用二分来查找,同算法一,也是先枚举每两个点,根据公式算出另外的两个点,不过,直接用二分来查找这两个点是否存在,当然了,事先需要对输入的坐标排个序,先按x坐标从小到大排序,相同的x的点以y坐标从小到大排序,二分检测时候,先找到与当前被检索的点的x坐标相同的所有点的下标范围,然后再次在这个范围里面再次二分查找是否存在与其y坐标相同的点.........
需要注意的是这种方法,对于同一个正方形来说,因为与两条对角线,所以会算了两次,所以最后输出的时候需要除以2,呵呵
Code1:
1 #include < stdio.h >
2 #include < math.h >
3 #include < string .h >
4 #define max 1005
5 #define pianyi 20005
6 #define prime 39997
7 #define len 50000
8 int n,i,j,start,sum,count,pos[max][ 2 ];
9 double x[ 3 ],y[ 3 ];
10
11 struct node
12 {
13 int px,py;
14 int next;
15} hash[len];
16
17 void cal( int a, int b)
18 {
19 double x0=(double)(pos[a][0]+pos[b][0])/2,y0=(double)(pos[a][1]+pos[b][1])/2;
20 if((pos[b][1]-pos[a][1])*(pos[b][0]-pos[a][0])>0)
21 {
22 x[1]=x0-fabs(pos[b][1]-pos[a][1])/2;
23 x[2]=x0+fabs(pos[b][1]-pos[a][1])/2;
24 y[1]=y0+fabs(pos[b][0]-pos[a][0])/2;
25 y[2]=y0-fabs(pos[b][0]-pos[a][0])/2;
26 }
27 else
28 {
29 x[1]=x0-fabs(pos[b][1]-pos[a][1])/2;
30 x[2]=x0+fabs(pos[b][1]-pos[a][1])/2;
31 y[1]=y0-fabs(pos[b][0]-pos[a][0])/2;
32 y[2]=y0+fabs(pos[b][0]-pos[a][0])/2;
33 }
34}
35 int Hash2( int x, int y)
36 {
37 int now=x%prime;
38 while(hash[now].next!=-1)
39 {
40 if(hash[hash[now].next].py==y)return 1;
41 now=hash[now].next;
42 }
43 return 0;
44}
45 void Hash( int k)
46 {
47 int now=k%prime;
48 while(hash[now].next!=-1)now=hash[now].next;
49 hash[start].next=-1;
50 hash[now].next=start;
51 start++;
52}
53 int main()
54 {
55 while(scanf("%d",&n)!=EOF&&n)
56 {
57 start=prime+10;
58 memset(hash,-1,sizeof(hash));
59 for(i=0;i<n;i++)
60 {
61 scanf("%d%d",&pos[i][0],&pos[i][1]);
62 hash[start].px=pos[i][0];
63 hash[start].py=pos[i][1];
64 Hash(pos[i][0]+pianyi);
65 }
66 count=0;
67 for(i=0;i<n-1;i++)
68 for(j=i+1;j<n;j++)
69 {
70 int res1,res2;
71 cal(i,j);
72 int t1=(int)x[1],t2=(int)x[2],t3=(int)y[1],t4=(int)y[2];
73 if(t1!=x[1]||t2!=x[2]||t3!=y[1]||t4!=y[2])continue;
74 res1=Hash2((int)x[1]+pianyi,(int)y[1]);
75 res2=Hash2((int)x[2]+pianyi,(int)y[2]);
76 if(res1&&res2)count++;
77 }
78 printf("%d\n",count/2);
79 }
80 return 0;
81}
82
83
Code2:
1 #include < stdio.h >
2 #include < stdlib.h >
3 #include < math.h >
4 #include < string .h >
5 #define max 2005
6
7 int n,i,j,start,sum,count;
8 double x[ 3 ],y[ 3 ];
9
10 struct node
11 {
12 int px,py;
13} pos[max];
14
15 int cmp( const void * a, const void * b)
16 {
17 struct node *c=(node *)a;
18 struct node *d=(node *)b;
19 if(c->px!=d->px)return c->px-d->px;
20 else return c->py-d->py;
21}
22
23 int search2( int low, int high, int y)
24 {
25 int mid;
26 while(low<=high&&low>=0&&high<n)
27 {
28 mid=(low+high)/2;
29 if(y<pos[mid].py)high=mid-1;
30 else if(y>pos[mid].py)low=mid+1;
31 else return 1;
32 }
33 return 0;
34}
35
36 int search( int low, int high, int x, int y)
37 {
38 int mid;
39 while(low<=high&&low>=0&&high<n)
40 {
41 mid=(low+high)/2;
42 if(x<pos[mid].px)high=mid-1;
43 else if(x>pos[mid].px)low=mid+1;
44 else
45 {
46 int start=mid,end=mid;
47 while(pos[start].px==x&&start>=0)start--;
48 while(pos[end].px==x&&end<n)end++;
49 return search2(start+1,end-1,y);
50 }
51 }
52 return 0;
53}
54
55
56
57 void cal( int a, int b)
58 {
59 double x0=(double)(pos[a].px+pos[b].px)/2,y0=(double)(pos[a].py+pos[b].py)/2;
60 if((pos[b].py-pos[a].py)*(pos[b].px-pos[a].px)>0)
61 {
62 x[1]=x0-fabs(pos[b].py-pos[a].py)/2;
63 x[2]=x0+fabs(pos[b].py-pos[a].py)/2;
64 y[1]=y0+fabs(pos[b].px-pos[a].px)/2;
65 y[2]=y0-fabs(pos[b].px-pos[a].px)/2;
66 }
67 else
68 {
69 x[1]=x0-fabs(pos[b].py-pos[a].py)/2;
70 x[2]=x0+fabs(pos[b].py-pos[a].py)/2;
71 y[1]=y0-fabs(pos[b].px-pos[a].px)/2;
72 y[2]=y0+fabs(pos[b].px-pos[a].px)/2;
73 }
74}
75
76 int main()
77 {
78 while(scanf("%d",&n)!=EOF&&n)
79 {
80 for(i=0;i<n;i++)scanf("%d%d",&pos[i].px,&pos[i].py);
81 qsort(pos,n,sizeof(pos[0]),cmp);
82 count=0;
83 for(i=0;i<n-1;i++)
84 for(j=i+1;j<n;j++)
85 {
86 int res1,res2;
87 cal(i,j);
88 int t1=(int)x[1],t2=(int)x[2],t3=(int)y[1],t4=(int)y[2];
89 if(t1!=x[1]||t2!=x[2]||t3!=y[1]||t4!=y[2])continue;
90 res1=search(0,n-1,x[1],y[1]);
91 if(!res1)continue;
92 res2=search(0,n-1,x[2],y[2]);
93 if(res1&&res2)count++;
94 }
95 printf("%d\n",count/2);
96 }
97 return 0;
98}
99
100
1 #include < stdio.h >
2 #include < stdlib.h >
3 #include < math.h >
4 #include < string .h >
5 #define max 2005
6
7 int n,i,j,start,sum,count;
8 double x[ 3 ],y[ 3 ];
9
10 struct node
11 {
12 int px,py;
13} pos[max];
14
15 int cmp( const void * a, const void * b)
16 {
17 struct node *c=(node *)a;
18 struct node *d=(node *)b;
19 if(c->px!=d->px)return c->px-d->px;
20 else return c->py-d->py;
21}
22
23 int search2( int low, int high, int y)
24 {
25 int mid;
26 while(low<=high&&low>=0&&high<n)
27 {
28 mid=(low+high)/2;
29 if(y<pos[mid].py)high=mid-1;
30 else if(y>pos[mid].py)low=mid+1;
31 else return 1;
32 }
33 return 0;
34}
35
36 int search( int low, int high, int x, int y)
37 {
38 int mid;
39 while(low<=high&&low>=0&&high<n)
40 {
41 mid=(low+high)/2;
42 if(x<pos[mid].px)high=mid-1;
43 else if(x>pos[mid].px)low=mid+1;
44 else
45 {
46 int start=mid,end=mid;
47 while(pos[start].px==x&&start>=0)start--;
48 while(pos[end].px==x&&end<n)end++;
49 return search2(start+1,end-1,y);
50 }
51 }
52 return 0;
53}
54
55
56
57 void cal( int a, int b)
58 {
59 double x0=(double)(pos[a].px+pos[b].px)/2,y0=(double)(pos[a].py+pos[b].py)/2;
60 if((pos[b].py-pos[a].py)*(pos[b].px-pos[a].px)>0)
61 {
62 x[1]=x0-fabs(pos[b].py-pos[a].py)/2;
63 x[2]=x0+fabs(pos[b].py-pos[a].py)/2;
64 y[1]=y0+fabs(pos[b].px-pos[a].px)/2;
65 y[2]=y0-fabs(pos[b].px-pos[a].px)/2;
66 }
67 else
68 {
69 x[1]=x0-fabs(pos[b].py-pos[a].py)/2;
70 x[2]=x0+fabs(pos[b].py-pos[a].py)/2;
71 y[1]=y0-fabs(pos[b].px-pos[a].px)/2;
72 y[2]=y0+fabs(pos[b].px-pos[a].px)/2;
73 }
74}
75
76 int main()
77 {
78 while(scanf("%d",&n)!=EOF&&n)
79 {
80 for(i=0;i<n;i++)scanf("%d%d",&pos[i].px,&pos[i].py);
81 qsort(pos,n,sizeof(pos[0]),cmp);
82 count=0;
83 for(i=0;i<n-1;i++)
84 for(j=i+1;j<n;j++)
85 {
86 int res1,res2;
87 cal(i,j);
88 int t1=(int)x[1],t2=(int)x[2],t3=(int)y[1],t4=(int)y[2];
89 if(t1!=x[1]||t2!=x[2]||t3!=y[1]||t4!=y[2])continue;
90 res1=search(0,n-1,x[1],y[1]);
91 if(!res1)continue;
92 res2=search(0,n-1,x[2],y[2]);
93 if(res1&&res2)count++;
94 }
95 printf("%d\n",count/2);
96 }
97 return 0;
98}
99
100