洛谷题解洛谷题解题解:CF75B Facetook Priority Wall
xyx404
思路:
定义一个 unordered_set
用于标记出现过那些人,定义名字为 se。
定义一个 unordered_map
记录每个人所获得的分数,键为字符串类型,值为整形,定义名字为 person。
定义结构体用于存每个人的分数,此结构体排序用。
观察题目所给出的操作的输入格式,发现操作的标志一定是在这一行的第二个字符串,而这一行字符串的数量一定大于三,所以我们可以先输入前三个字符串,然后判断第二个字符串是什么操作。
如果第二个字符串等于 likes
那么第三个字符串就是第二个人的名字。
如果第二个字符串为 posted
或 commented
时,那么第二个人名的位置就在第四个字符串,我们把他输入进来。
在输入找到第二个人的名字后,我们用 erase
把第二个人名后面多余的 's
删除,使这个字符串只有人名,然后判断第一个人名和第二个人名中有没有淘淘,因为只有和淘淘互动了,他跟淘淘的因子分数才会增加,然后再判断下这些人名有没有在 se
里面出现过,如果没有出现过就把他加入到里面,最后把这些操作里的最后一个字符串输入进来就行了。
我们用创建一个 it 用于历遍 se,使他等于 se.begin()
,之后我们进入循环每次让 it++
循环条件为 it!=se.end()
,在循环过程中我们把每个人的名字以及分数存进结构体。
在循环结束后,我们用 sort
进行排序,排序函数为当分数一样时按名字的字典序排序,否则按分数的大小排序。
排序完后,我们输出,当现在输出的这个人的名字不是淘淘的名字时我们就输出。
代码:
#include<bits/stdc++.h> using namespace std; #define LL long long #define itn int #define ull unsigned long long int n; unordered_set<string>se; unordered_map<string,int>person; struct node{ string name; int soccer; }ren[110]; bool cmp(node x,node y){ if(x.soccer==y.soccer){ return x.name<y.name; } return x.soccer>y.soccer; } int main(){ string x;cin>>x; int n;cin>>n; while(n--){ string a,b,c; cin>>a>>b>>c; if(b=="likes"){ c.erase(c.size()-2);string Y=c; if(a==x||Y==x){ if(a!=x){ person[a]+=5; } if(Y!=x){ person[Y]+=5; } } if(!se.count(a))se.insert(a);if(!se.count(Y))se.insert(Y); cin>>c; } else if(b=="commented"){ cin>>c;c.erase(c.size()-2);string Y=c; if(a==x||Y==x){ if(a!=x){ person[a]+=10; } if(Y!=x){ person[Y]+=10; } } if(!se.count(a))se.insert(a);if(!se.count(Y))se.insert(Y); cin>>c; } else if(b=="posted"){ cin>>c;c.erase(c.size()-2);string Y=c; if(a==x||Y==x){ if(a!=x){ person[a]+=15; } if(Y!=x){ person[Y]+=15; } } if(!se.count(a))se.insert(a);if(!se.count(Y))se.insert(Y); cin>>c; } } auto it=se.begin(); for(int i=1;it!=se.end();it++,i++){ ren[i].name=*it; ren[i].soccer=person[*it]; } sort(ren+1,ren+1+se.size(),cmp); for(int i=1;i<=se.size();i++){ if(ren[i].name!=x)cout<<ren[i].name<<"\n"; } return 0; }
|