1. 程式人生 > >18.12.5 發現他,抓住他(並查集)&正方形(雜湊表)

18.12.5 發現他,抓住他(並查集)&正方形(雜湊表)

發現他,抓住他(10分)

題目內容:

一個城市中有兩個犯罪團伙A和B,你需要幫助警察判斷任意兩起案件是否是同一個犯罪團伙所為,警察所獲得的資訊是有限的。假設現在有N起案件(N<=100000),編號為1到N,每起案件由團伙A或團伙B所為。你將按時間順序獲得M條資訊(M<=100000),這些資訊分為兩類:

1. D [a] [b]

其中[a]和[b]表示兩起案件的編號,這條資訊表明它們屬於不同的團伙所為

2. A [a] [b]

其中[a]和[b]表示兩起案件的編號,這條資訊需要你回答[a]和[b]是否是同一個團伙所為

注意你獲得資訊的時間是有先後順序的,在回答的時候只能根據已經接收到的資訊做出判斷。

 

輸入格式:

第一行是測試資料的數量T(1<=T<=20)。
每組測試資料的第一行包括兩個數N和M,分別表示案件的數量和資訊的數量,其後M行表示按時間順序收到的M條資訊。

 

輸出格式:

對於每條需要回答的資訊,你需要輸出一行答案。如果是同一個團伙所為,回答"In the same gang.",如果不是,回答"In different gangs.",如果不確定,回答”Not sure yet."。

 

輸入樣例:

1
5 5
A 1 2
D 1 2
A 1 2
D 2 4
A 1 4

 

輸出樣例:

Not sure yet.
In different gangs.
In the same gang.
 1 #include <iostream>
 2 #include <string.h>
 3 #include <algorithm>
 4 #include <stack>
 5 #include <string>
 6 #include <math.h>
 7 #include <queue>
 8 #include <stdio.h>
 9
#include <string.h> 10 #include <vector> 11 #include <fstream> 12 #define maxn 100005 13 #define inf 999999 14 15 using namespace std; 16 int relation[maxn],set[maxn]; 17 int n, m; 18 19 void find(int x) { 20 if (x == set[x])return; 21 int father = set[x]; 22 find(father); 23 relation[x] = (relation[father] + relation[x]) % 2; 24 set[x] = set[father]; 25 } 26 27 void Union(int x, int y) { 28 find(x), find(y); 29 int fx = set[x], fy = set[y]; 30 set[fx] = fy; 31 relation[fx] = (1 + relation[y] + relation[x]) % 2; 32 } 33 34 void init() { 35 int kase; 36 scanf("%d", &kase); 37 while (kase--) { 38 scanf("%d%d", &n, &m); 39 for (int i = 1; i <= n; i++) { 40 set[i] = i; 41 relation[i] = 0; 42 } 43 while (m--) { 44 char cmd; 45 int x, y; 46 scanf("\n%c", &cmd); 47 if (cmd == 'D') { 48 scanf("%d%d", &x, &y); 49 Union(y, x); 50 } 51 else if (cmd == 'A') { 52 scanf("%d%d", &x, &y); 53 find(x), find(y); 54 if (set[x] != set[y]) 55 printf("Not sure yet.\n"); 56 else if (relation[x] == relation[y]) 57 printf("In the same gang.\n"); 58 else 59 printf("In different gangs.\n"); 60 } 61 } 62 } 63 } 64 65 int main() 66 { 67 init(); 68 return 0; 69 }
View Code

突然sssx……?我不是很明白這個用檢索怎麼做

正方形(10分)

題目內容:

給定直角座標系中的若干整點,請尋找可以由這些點組成的正方形,並統計它們的個數。

 

輸入格式:

包括多組資料,每組資料的第一行是整點的個數n(1<=n<=1000),其後n行每行由兩個整陣列成,表示一個點的x、y座標。輸入保證一組資料中不會出現相同的點,且座標的絕對值小於等於20000。輸入以一組n=0的資料結尾。

 

輸出格式:

對於每組輸入資料,輸出一個數,表示這組資料中的點可以組成的正方形的數量。

 

輸入樣例:

4
1 0
0 1
1 1
0 0
9
0 0
1 0
2 0
0 2
1 2
2 2
0 1
1 1
2 1
4
-2 5
3 7
0 0
5 2
0

 

輸出樣例:

1
6
1
 1 #include <iostream>
 2 #include <string.h>
 3 #include <algorithm>
 4 #include <stack>
 5 #include <string>
 6 #include <math.h>
 7 #include <queue>
 8 #include <stdio.h>
 9 #include <string.h>
10 #include <vector>
11 #include <fstream>
12 #define maxn 100005
13 #define inf 999999
14 
15 using namespace std;
16 int n;
17 
18 struct point {
19     int x, y;
20     int count;
21     point() {
22         x = 0, y = 0, count = 0;
23     }
24 }Hash[1100], all[1100];
25 
26 int p2hash(point x) {
27     return (x.x*x.x + x.y*x.y) % 1003;
28 }
29 
30 void put(point a) {
31     int i = p2hash(a);
32     while (Hash[i].count != 0) {
33         i++;
34     }
35     Hash[i].x = a.x, Hash[i].y = a.y;
36     Hash[i].count++;
37 }
38 
39 bool find(point a) {
40     int i = p2hash(a);
41     while (Hash[i].count != 0) {
42         if (Hash[i].x == a.x&&Hash[i].y == a.y)
43             return true;
44         i++;
45     }
46     return false;
47 }
48 
49 void init() {
50     int ans = 0;
51     for (int i = 1; i <= n; i++) {
52         int x, y;
53         scanf("%d%d", &x, &y);
54         all[i].x = x, all[i].y = y;
55         put(all[i]);
56     }
57     for(int i=1;i<=n;i++)
58         for (int j = 1; j <= n; j++) {
59             if (i == j)continue;
60             point a1, a2;
61             int dx = all[j].x - all[i].x, dy = all[i].y - all[j].y;
62             a1.x = all[i].x + dy;
63             a1.y = all[i].y + dx;
64             a2.x = all[j].x + dy;
65             a2.y = all[j].y + dx;
66             if (find(a1) && find(a2))
67                 ans++;
68         }
69     printf("%d\n", ans/4);
70 }
71 
72 int main()
73 {
74     while(scanf("%d",&n)&&n)
75         init();
76     return 0;
77 }
View Code

兩個點確定另外兩個點,然後檢索。