题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805344776077312
题意:
有m对朋友关系,每个人用4为数字的编号表示,如果是负数表示这是女生。
给定k个查询,对于要查的人a和b,问有多少对朋友(c,d)使得c和a是同性,d和b是同性,且c和d是朋友。
思路:
枚举a的所有同性朋友,枚举b的所有同性朋友,看他们是不是朋友。
首先用了map离散化了一下给了个id,可能是这里搞来搞去T了最后一组数据。
实际上简单点可以直接用c++ 11标准里的stoi来做,感觉PAT老是碰到这个函数。
由于标号是唯一的,所以一个人只需要存储他的同性朋友就可以了。
开bool的话二维的1e5也是开的下的。
要注意枚举的时候如果直接碰到了a或b都要跳过。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<map> 4 #include<set> 5 #include<iostream> 6 #include<cstring> 7 #include<algorithm> 8 #include<vector> 9 #include<cmath> 10 #include<stack> 11 #include<queue> 12 13 #define inf 0x7fffffff 14 using namespace std; 15 typedef long long LL; 16 typedef pair<string, string> pr; 17 18 int n, m, k; 19 int id = 1; 20 bool fri[10000][10000]; 21 vector<int>samefri[10000]; 22 23 struct node{ 24 int c, d; 25 node(){ 26 } 27 node(int _c, int _d){ 28 c = _c; 29 d = _d; 30 } 31 }; 32 33 bool cmp(node a, node b) 34 { 35 if(a.c == b.c)return a.d < b.d; 36 else return a.c < b.c; 37 } 38 39 int main() 40 { 41 scanf("%d%d", &n, &m); 42 for(int i = 1; i <= m; i++){ 43 string a, b; 44 cin>>a>>b; 45 int first = abs(stoi(a)); 46 int second = abs(stoi(b)); 47 48 fri[first][second] = true; 49 fri[second][first] = true; 50 if(a.length() == b.length()){ 51 samefri[first].push_back(second); 52 samefri[second].push_back(first); 53 } 54 } 55 56 scanf("%d", &k); 57 while(k--){ 58 string a, b; 59 cin>>a>>b; 60 61 int cnt = 0; 62 vector<node>ans; 63 int first = abs(stoi(a)), second = abs(stoi(b)); 64 for(int i = 0; i < samefri[first].size(); i++){ 65 int c = samefri[first][i]; 66 if(c == second)continue; 67 for(int j = 0; j < samefri[second].size(); j++){ 68 int d = samefri[second][j]; 69 if(d == first)continue; 70 if(fri[c][d]){ 71 cnt++; 72 ans.push_back(node(c, d)); 73 //cout<<a<<" "<<b<<endl<<endl; 74 } 75 } 76 } 77 78 printf("%d ", cnt); 79 sort(ans.begin(), ans.end(), cmp); 80 for(int i = 0; i < cnt; i++){ 81 printf("%04d %04d ", ans[i].c, ans[i].d); 82 } 83 } 84 return 0; 85 }