7-8 悄悄关注 (25 分)
新浪微博上有个“悄悄关注”,一个用户悄悄关注的人,不出现在这个用户的关注列表上,但系统会推送其悄悄关注的人发表的微博给该用户。现在我们来做一回网络侦探,根据某人的关注列表和其对其他用户的点赞情况,扒出有可能被其悄悄关注的人。
输入格式:
输入首先在第一行给出某用户的关注列表,格式如下:
人数N 用户1 用户2 …… 用户N
其中N是不超过5000的正整数,每个用户i(i=1, …, N)是被其关注的用户的ID,是长度为4位的由数字和英文字母组成的字符串,各项间以空格分隔。
之后给出该用户点赞的信息:首先给出一个不超过10000的正整数M,随后M行,每行给出一个被其点赞的用户ID和对该用户的点赞次数(不超过1000),以空格分隔。注意:用户ID是一个用户的唯一身份标识。题目保证在关注列表中没有重复用户,在点赞信息中也没有重复用户。
输出格式:
我们认为被该用户点赞次数大于其点赞平均数、且不在其关注列表上的人,很可能是其悄悄关注的人。根据这个假设,请你按用户ID字母序的升序输出可能是其悄悄关注的人,每行1个ID。如果其实并没有这样的人,则输出“Bing Mei You”。
输入样例1:
10 GAO3 Magi Zha1 Sen1 Quan FaMK LSum Eins FatM LLao
8
Magi 50
Pota 30
LLao 3
Ammy 48
Dave 15
GAO3 31
Zoro 1
Cath 60
输出样例1:
Ammy
Cath
Pota
输入样例2:
11 GAO3 Magi Zha1 Sen1 Quan FaMK LSum Eins FatM LLao Pota
7
Magi 50
Pota 30
LLao 48
Ammy 3
Dave 15
GAO3 31
Zoro 29
输出样例2:
Bing Mei You
这是前几天的模拟天梯赛的题目,本来应该放到补题里,介于知识点比较多,就单独拿出来引起重视。首先这道题相当于拿一串字符串对前边的字符串进行比较,比赛的时候思路也比较单一,先想暴力做法。
把一开始的名字存到st数组里,然后把后面的名字跟前边数组里的名字挨着比较,最后对平均值满足条件的名字输出即可,这种做法会超时。
所以我发现了两重循环的问题,此时我把第二重循环用字典树优化了一下就OK了。
代码如下:
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e5+10;
double k;
int n;
int idx;
int son[N][1000];
char st[N][5];
int cnt[N];
struct qiao
{string name;double x;
}qi[N],pi[N];
bool cmp(qiao a,qiao b)
{return a.name<b.name;
}
void insert(string x)
{int p=0;for(int i=0;i<x.size();i++){ int u=x[i]-'0';if(!son[p][u]) son[p][u]=++idx;p=son[p][u];}cnt[p]++;return ;
}
int query(string x)
{int p=0;for(int i=0;i<x.size();i++){int u=x[i]-'0';if(!son[p][u]) return 0;p=son[p][u]; }return cnt[p];
}
int s=0;
int z=0;
int main()
{scanf("%d",&n);for(int i=1;i<=n;i++){ string str;scanf("%s",st[i]);str=st[i];insert(st[i]);}double res=0;scanf("%lf",&k);for(int i=1;i<=k;i++){ cin>>qi[i].name>>qi[i].x;res+=qi[i].x;}double ave=res/k;for(int i=1;i<=k;i++){ int flag=0;if(qi[i].x<=ave) continue;if(query(qi[i].name)!=0){flag=1;}if(flag==1) continue;pi[++s]=qi[i];}sort(pi+1,pi+1+s,cmp);if(s==0) cout<<"Bing Mei You"<<endl;else {for(int i=1;i<=s;i++){cout<<pi[i].name<<endl;}}
}
但是我通过观察cndn大佬的代码发现这道题其实可以做的非常简便,不过这要求我熟练掌握STL容器,所以我用这道题相当于复习一下之前STL容器的知识。那么先看一下网上大佬用STL做的代码:原博客地址
#include <bits/stdc++.h>
#include <iostream>
#include <map>
#include <string>
using namespace std;
set<string>s;
map<string,int>p,pp;
int main()
{int i,n,m,sum=0,t;string name,a[10001];cin>>n;while(n--){cin>>name;p[name]=1;}cin>>m;for(i=0;i<m;i++){cin>>a[i]>>t;pp[a[i]]=t;sum+=t;}sum=sum/m;for(i=0;i<m;i++){if(p[a[i]]==0&&pp[a[i]]>sum)s.insert(a[i]);}if(s.empty()){puts("Bing Mei You");return 0;}set<string>::iterator it;for(it=s.begin();it!=s.end();it++)cout<<*it<<endl;return 0;
}
之前有了解过STL容器的知识,但是并没有把这些容器的输出及使用研究透彻。
首先这是一个set的输入输出,需要用到一些迭代器的相关知识:
这是一个数字,那上面那个题相应的就是输出字符串了,不多举例。
而map的具体使用在之前stl容器的博客中写过:
即便是<string,int>的mp,也可以通过string充当数组下标进行输入输出。这个巧妙的方法在这道题目体现的淋漓尽致。