18.12.5 發現他,抓住他(並查集)&正方形(雜湊表)
阿新 • • 發佈:2018-12-05
發現他,抓住他(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> 9View Code#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 }
突然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
兩個點確定另外兩個點,然後檢索。