转载请注明出处:優 YoU http://user.qzone.qq.com/289065406/blog/1304781008
POJ2002 的山寨题,把数据规模从 2002 的 n=1000 修改为 n=2000 就能 AC 了
注意这种题一定不能图方便用 STL 的 map 标记, map 效率不高,必定超时的 .
解题思路参看POJ2002:
http://blog.csdn.net/lyy289065406/article/details/6647405
1 // Memory Time
2 // 336K 313MS
3
4 #include < iostream >
5 using namespace std;
6
7 const int prime = 1999 ; // 长度为n区间的最大素数 (本题n=2000)
8
9 typedef class
10 {
11 public :
12 int x,y;
13 }Node;
14
15 typedef class HashTable
16 {
17 public :
18 int x,y; // 标记key值对应的x,y
19 HashTable * next; // 当出现地址冲突时,开放寻址
20
21 HashTable() // Initial
22 {
23 next = 0 ;
24 }
25 }Hashtable;
26
27 Node pos[ 2001 ];
28 Hashtable * hash[prime]; // hash[]是指针数组,存放地址
29
30 void insert_vist( int k)
31 {
32 int key = ((pos[k].x * pos[k].x) + (pos[k].y * pos[k].y)) % prime + 1 ; // +1是避免==0
33 // 使key从[0~1998]后移到[1~1999]
34 if ( ! hash[key])
35 {
36 Hashtable * temp = new Hashtable;
37 temp -> x = pos[k].x;
38 temp -> y = pos[k].y;
39 hash[key] = temp;
40 }
41 else // hash[key]已存地址,地址冲突
42 {
43 Hashtable * temp = hash[key];
44
45 while (temp -> next) // 开放寻址,直至next为空
46 temp = temp -> next;
47
48 temp -> next = new HashTable; // 申请新结点,用next指向,记录x、y
49 temp -> next -> x = pos[k].x;
50 temp -> next -> y = pos[k].y;
51 }
52 return ;
53 }
54
55 bool find( int x, int y)
56 {
57 int key = ((x * x) + (y * y)) % prime + 1 ;
58
59 if ( ! hash[key]) // key对应的地址不存在
60 return false ;
61 else
62 {
63 Hashtable * temp = hash[key];
64
65 while (temp)
66 {
67 if (temp -> x == x && temp -> y == y)
68 return true ;
69
70 temp = temp -> next;
71 }
72 }
73
74 return false ;
75 }
76
77 int main( void )
78 {
79 int n;
80 while (cin >> n)
81 {
82 if ( ! n)
83 break ;
84
85 memset(hash, 0 , sizeof (hash)); // 0 <-> NULL
86
87 for ( int k = 1 ;k <= n;k ++ )
88 {
89 cin >> pos[k].x >> pos[k].y;
90 insert_vist(k); // 插入哈希表,标记散点
91 }
92
93 int num = 0 ; // 正方形的个数
94 for ( int i = 1 ;i <= n - 1 ;i ++ )
95 for ( int j = i + 1 ;j <= n;j ++ )
96 {
97 int a = pos[j].x - pos[i].x;
98 int b = pos[j].y - pos[i].y;
99
100 int x3 = pos[i].x + b;
101 int y3 = pos[i].y - a;
102 int x4 = pos[j].x + b;
103 int y4 = pos[j].y - a;
104
105 if (find(x3,y3) && find(x4,y4))
106 num ++ ;
107
108 x3 = pos[i].x - b;
109 y3 = pos[i].y + a;
110 x4 = pos[j].x - b;
111 y4 = pos[j].y + a;
112
113 if (find(x3,y3) && find(x4,y4))
114 num ++ ;
115 }
116
117 cout << num / 4 << endl; // 同一个正方形枚举了4次
118 }
119 return 0 ;
120 }