1139 First Contact (字符串转编号,一不注意就凉凉四个小时???)

以后借助map实现字符串转编号,编号一律从 1开始,不要问为什么,血泪教训!!!

大致题意就是A看上了B,A要通过同性别朋友C,如果C认识D,且D是B的同性别朋友,那么A就可以追求B了。

方法一:DFS暴力枚举法,凉凉~~。

 1 #include<iostream>
 2 #include<vector>
 3 #include<unordered_map>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 struct node {
 8     int a,b;
 9 };
10 const int maxn = 310;
11 int n,m,k;
12 
13 vector<int> G[maxn],path;
14 bool visited[maxn] = {false};
15 vector<node> ans;
16 bool cmp(node& a,node& b) {
17     if(a.a != b.a) return a.a < b.a;
18     else return a.b < b.b;
19 }
20 unordered_map<string,int> IDtoInt;
21 unordered_map<int,string> IntToID;
22 int num = 1;
23 int getID(string id) {
24     if(IDtoInt.count(id) == 0) {
25         IDtoInt[id] = num;
26         IntToID[num++] = id;
27     }
28     return IDtoInt[id];
29 }
30 
31 void DFS(int now,int end,int len) {
32     if(len == 4) {
33         if(now == end) {
34             path.push_back(end);
35             if(IntToID[path[0]].size() == IntToID[path[1]].size()  &&IntToID[path[2]].size() == IntToID[path[3]].size() )
36                 ans.push_back({abs(stoi(IntToID[path[1]])),abs(stoi(IntToID[path[2]]))});
37             path.pop_back();
38         }
39         return ;
40     }
41     if(now == end && len < 4) return;
42     visited[now] = true;
43     path.push_back(now);
44     for(int i = 0; i < G[now].size(); ++i) {
45         if(visited[G[now][i]] == false)
46             DFS(G[now][i],end,len+1);
47     }
48     visited[now] = false;
49     path.pop_back();
50 }
51 int main() {
52     scanf("%d%d",&n,&m);
53     string a,b; //必须考虑 -0000,0000的情况,所以用string
54     for(int i = 0; i < m; ++i) {
55         cin>>a>>b;
56         int u = getID(a),v = getID(b);
57         G[u].push_back(v);
58         G[v].push_back(u);
59     }
60     scanf("%d",&k);
61     while(k--) {
62         cin>>a>>b;
63         ans.clear();
64         DFS(IDtoInt[a],IDtoInt[b],1);
65         sort(ans.begin(),ans.end(),cmp);
66         printf("%d\n",ans.size());
67         for(int i = 0; i < ans.size(); ++i) printf("%04d %04d\n",ans[i].a,ans[i].b);
68     }
69     return 0;
70 }

方法二:

用map建立 ID与编号的对应关系。

用邻接表,保存一对顶点的朋友关系。

用邻接矩阵,保存某个人的所有同性别朋友。

如果A的同性朋友是C,B的同性朋友是D,若C与D是朋友关系,那么A可以追求B。

注意点:

1,编号必须从1开始,因为给出的ID可能非法,其对应编号为0表示未找到这个人,不然测试点 5无法通过。

2,注意输入为 -0000的情况,必须用string接受 -0000

 1 #include<iostream>
 2 #include<vector>
 3 #include<algorithm>
 4 #include<unordered_map>
 5 using namespace std;
 6 const int maxn = 320;
 7 struct node {
 8     int a,b;
 9 };
10 int n,m,k,G[maxn][maxn];
11 vector<int> adj[maxn];
12 bool cmp(node a,node b) {
13     if(a.a != b.a)  return a.a < b.a;
14     else return a.b < b.b;
15 }
16 unordered_map<string,int> IDtoInt;
17 unordered_map<int,string> IntToID;
18 int num = 1; //写成 num = 0时,因为输入非法ID时IDtoInt[ID] = 0为非法结果,合法编号与非法结果冲突!!所以编号num必须从1开始。这就是导致测试点5答案错误的原因,排查了我5个小时,呵呵,呜呜~~
19 int getID(string id) {
20     if(!IDtoInt.count(id)) {
21         IDtoInt[id] = num;
22         IntToID[num++] = id;
23     }
24     return IDtoInt[id];
25 }
26 int main() {
27     fill(G[0],G[0]+maxn*maxn,0);
28     cin>>n>>m;
29     string a,b;
30     for(int i = 0; i < m; ++i) {
31         cin>>a>>b;//这样读取的原因是有易错点:-0000
32         int u = getID(a),v = getID(b);
33         G[u][v] = G[v][u] = 1;//朋友关系
34         if(a.size() == b.size()) { //同性朋友关系
35             adj[u].push_back(v);
36             adj[v].push_back(u);
37         }
38     }
39     cin>>k;
40     while(k--) {
41         cin>>a>>b;
42         vector<node> ans;
43         int u = IDtoInt[a],v = IDtoInt[b];
44         for(int i = 0; i < adj[u].size(); ++i) { //找u的同性朋友 C
45             int c = adj[u][i];
46             for(int j = 0; j < adj[v].size(); ++j) {//找v的同性朋友 D
47                 int d = adj[v][j];
48                 if(v == c || u == d) continue;
49                 if(G[c][d]) ans.push_back({abs(stoi(IntToID[c])),abs(stoi(IntToID[d]))});
50             }
51         }
52         sort(ans.begin(),ans.end(),cmp);
53         printf("%d\n",ans.size());
54         for(int i = 0; i < ans.size(); ++i)
55             printf("%04d %04d\n",ans[i].a,ans[i].b);
56     }
57     return 0;
58 }

方法三:

开很大的数组,直接映射ID,无需使用map。

 1 #include<iostream>
 2 #include<vector>
 3 #include<algorithm>
 4 
 5 using namespace std;
 6 const int maxn = 10000;
 7 struct node {
 8     int a,b;
 9 };
10 int n,m,k,G[maxn][maxn]= {0};
11 vector<int> adj[maxn];
12 bool cmp(node a,node b) {
13     if(a.a != b.a)  return a.a < b.a;
14     else return a.b < b.b;
15 }
16 int main() {
17     cin>>n>>m;
18     string a,b;
19     for(int i = 0; i < m; i++) {
20         cin>>a>>b;//这样读取的原因是有易错点:-0000
21         int u = abs(stoi(a)),v = abs(stoi(b));
22         G[u][v] = G[v][u] = 1;
23         if(a.size() == b.size()) {//同性朋友
24             adj[u].push_back(v);
25             adj[v].push_back(u);
26         }
27     }
28     cin>>k;
29     while(k--) {
30         cin>>a>>b;
31         vector<node> ans;
32         int u = abs(stoi(a)),v = abs(stoi(b));
33         for(int i = 0; i < adj[u].size(); i++) {
34             int c = adj[u][i];
35             for(int j = 0; j < adj[v].size(); j++) {
36                 int d = adj[v][j];
37                 if(v == c || u == d) continue;
38                 if(G[c][d]) ans.push_back({c,d});
39             }
40         }
41         sort(ans.begin(),ans.end(),cmp);
42         printf("%d\n",ans.size());
43         for(int i = 0; i < ans.size(); i++) {
44             printf("%04d %04d\n",ans[i].a,ans[i].b);//%04d为易错点
45         }
46     }
47     return 0;
48 }

 

posted @ 2020-03-15 18:01  tangq123  阅读(224)  评论(0编辑  收藏  举报