7-1 电话聊天狂人
给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人。
输入格式:
输入首先给出正整数N(≤105),为通话记录条数。随后N行,每行给出一条通话记录。简单起见,这里只列出拨出方和接收方的11位数字构成的手机号码,其中以空格分隔。
输出格式:
在一行中给出聊天狂人的手机号码及其通话次数,其间以空格分隔。如果这样的人不唯一,则输出狂人中最小的号码及其通话次数,并且附加给出并列狂人的人数。
输入样例:
4
13005711862 13588625832
13505711862 13088625832
13588625832 18087925832
15005713862 13588625832
输出样例:
13588625832 3
题目分析:两个集合共有的元素的个数 / 两个集合合在一起成为一个集合(无重复元素)的个数 。
#include <bits/stdc++.h>
using namespace std;
map<string,int> f;
map<string,int>::iterator it;//迭代器 用来访问map f
int main()
{
int n;
cin>>n;
string s1,s2;
while(n--)
{
cin>>s1>>s2;
f[s1]++;
f[s2]++;
}
int mx=0,cnt;
string id;
for(it=f.begin(); it!=f.end(); it++)
{
if(it->second>mx)
{
mx=it->second;
id=it->first;
cnt=1;
}
else if(it->second==mx)cnt++;
}
cout<<id<<" "<<mx;
if(cnt>1)
cout<<" "<<cnt;
return 0;
}
7-2 两个有序序列的中位数
已知有两个等长的非降序序列S1, S2, 设计函数求S1与S2并集的中位数。有序序列A0,A1,⋯,AN−1的中位数指A(N−1)/2的值,即第⌊(N+1)/2⌋个数(A0为第1个数)。
输入格式:
输入分三行。第一行给出序列的公共长度N(0<N≤100000),随后每行输入一个序列的信息,即N个非降序排列的整数。数字用空格间隔。
输出格式:
在一行中输出两个输入序列的并集序列的中位数。
输入样例1:
5
1 3 5 7 9
2 3 4 5 6
输出样例1:
4
输入样例2:
6
-100 -10 1 1 1 1
-50 0 2 3 4 5
输出样例2:
1
#include<bits/stdc++.h>
using namespace std;
int n,d,c[200000];
int main(){
cin>>n;
for(int i=0; i<2*n; i++)cin>>c[i];
sort(c+0,c+2*n); //升序排序
cout<<c[n-1];
return 0;
}
7-3 词频统计
请编写程序,对一段英文文本,统计其中所有不同单词的个数,以及词频最大的前10%的单词。
所谓“单词”,是指由不超过80个单词字符组成的连续字符串,但长度超过15的单词将只截取保留前15个单词字符。而合法的“单词字符”为大小写字母、数字和下划线,其它字符均认为是单词分隔符。
输入格式:
输入给出一段非空文本,最后以符号#
结尾。输入保证存在至少10个不同的单词。
输出格式:
在第一行中输出文本中所有不同单词的个数。注意“单词”不区分英文大小写,例如“PAT”和“pat”被认为是同一个单词。
随后按照词频递减的顺序,按照词频:单词
的格式输出词频最大的前10%的单词。若有并列,则按递增字典序输出。
输入样例:
This is a test.
The word "this" is the word with the highest frequency.
Longlonglonglongword should be cut off, so is considered as the same as longlonglonglonee. But this_8 is different than this, and this, and this...#
this line should be ignored.
输出样例:(注意:虽然单词the
也出现了4次,但因为我们只要输出前10%(即23个单词中的前2个)单词,而按照字母序,the
排第3位,所以不输出。)
23
5:this
4:is
#include<bits/stdc++.h>
using namespace std;
typedef pair<string, int> PII;
map<string,int> mp;
vector<PII> q;
bool cmp(PII a,PII b) // 自定义排序方式
{
if(a.second!=b.second) return a.second>b.second; // 出现的次数
else
return a.first<b.first; // 字母序
}
int main()
{
string s;
char x;
while(~scanf("%c",&x)&&x!='#') // 一个字符一个字符的读 遇到 # 结束
{
if( (x>='A'&&x<='Z') || (x>='a'&&x<='z') || (x>='0'&&x<='9') || x=='_')
{
if(x>='A'&&x<='Z') x=x-'A'+'a'; // 都转化成小写
if(s.size()<15) s+=x; // 如果大于 长度15 只要前十五个
}
else // 遇到非合法字符
{
if(s.size()>0) mp[s]++,s.clear(); // 存到map<string,int> 中去
}
}
for(auto it=mp.begin();it!=mp.end();it++) // 把map 中的信息转入到 vector中去 也可转到结构体中 用结构体解决
q.push_back({it->first,it->second});
sort(q.begin(),q.end(),cmp); // 按定义的方式排序
cout<<q.size()<<endl; // 输出一共单词个数
int l=q.size()/10;
for(int i=0;i<l;i++) // 遍历前10%
cout<<q[i].second<<':'<<q[i].first<<endl;
return 0;
}
7-4 集合相似度
给定两个整数集合,它们的相似度定义为:Nc/Nt×100%。其中Nc是两个集合都有的不相等整数的个数,Nt是两个集合一共有的不相等整数的个数。你的任务就是计算任意一对给定集合的相似度。
输入格式:
输入第一行给出一个正整数N(≤50),是集合的个数。随后N行,每行对应一个集合。每个集合首先给出一个正整数M(≤104),是集合中元素的个数;然后跟M个[0,109]区间内的整数。
之后一行给出一个正整数K(≤2000),随后K行,每行对应一对需要计算相似度的集合的编号(集合从1到N编号)。数字间以空格分隔。
输出格式:
对每一对需要计算的集合,在一行中输出它们的相似度,为保留小数点后2位的百分比数字。
输入样例:
3
3 99 87 101
4 87 101 5 87
7 99 101 18 5 135 18 99
2
1 2
1 3
输出样例:
50.00%
33.33%
#include <bits/stdc++.h>
using namespace std;
int main()
{
set<int> a[55];//集合
int n;
cin>>n;
for(int j=1; j<=n; j++)
{
int m;
cin>>m;
int i;
for(i=0; i<m; i++)
{
int c;
cin>>c;
a[j].insert(c);
}
}
int x;
cin>>x;
while(x--)
{
int k1,k2;
cin>>k1>>k2;
double sum=a[k2].size();
double num=0,num1;
set<int>::iterator it;//迭代器,用于访问集合中的元素
for(it=a[k1].begin(); it!=a[k1].end(); it++)
{
if(!a[k2].count(*it))//用于判断集合K1中的it元素是否在集合K2中出现过;count是为了给元素计数,在集合中的值只有0和1,因为集合中无重复元素 num++;
num++;
}
num1=a[k1].size()-num;
printf("%.2lf%%\n",100*num1/(sum+num));
}
return 0;
}
7-5 悄悄关注
新浪微博上有个“悄悄关注”,一个用户悄悄关注的人,不出现在这个用户的关注列表上,但系统会推送其悄悄关注的人发表的微博给该用户。现在我们来做一回网络侦探,根据某人的关注列表和其对其他用户的点赞情况,扒出有可能被其悄悄关注的人。
输入格式:
输入首先在第一行给出某用户的关注列表,格式如下:
人数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
#include <bits/stdc++.h>
using namespace std;
map <string,int> z;//存id和对应的赞的数量
set <string> p;//存id
int main()
{
int n;
cin>>n;
int i;
for(i=0; i<n; i++)
{
string s;
cin>>s;
p.insert(s);
}
int m,sum=0;
cin>>m;
for(i=0; i<m; i++)
{
string a;
int b;
cin>>a>>b;//点赞的人的id和赞数
z[a]=b;
sum+=b;
}
int ave=sum/m;
int flag=0;
for(auto it=z.begin(); it!=z.end(); it++)
{
if(!p.count(it->first)&&it->second>ave)//该人是否在关注列表,赞数是否超过平均值(判断是否被悄悄关注)
{
cout<<it->first<<endl;
flag=1;
}
}
if(flag==0)
cout<<"Bing Mei You"<<endl;
return 0;
}
7-6 单身狗
“单身狗”是中文对于单身人士的一种爱称。本题请你从上万人的大型派对中找出落单的客人,以便给予特殊关爱。
输入格式:
输入第一行给出一个正整数 N(≤50000),是已知夫妻/伴侣的对数;随后 N 行,每行给出一对夫妻/伴侣——为方便起见,每人对应一个 ID 号,为 5 位数字(从 00000 到 99999),ID 间以空格分隔;之后给出一个正整数 M(≤10000),为参加派对的总人数;随后一行给出这 M 位客人的 ID,以空格分隔。题目保证无人重婚或脚踩两条船。
输出格式:
首先第一行输出落单客人的总人数;随后第二行按 ID 递增顺序列出落单的客人。ID 间用 1 个空格分隔,行的首尾不得有多余空格。
输入样例:
3
11111 22222
33333 44444
55555 66666
7
55555 44444 10000 88888 22222 11111 23333
输出样例:
5
10000 23333 44444 55555 88888
#include <bits/stdc++.h>
using namespace std;
map<string,string>m;
set<string>s,s1,s2;
int main()
{
int n;
cin>>n;
int i;
for(i=0; i<n; i++)
{
string a,b;
cin>>a>>b;
m[a]=b;//情侣间互相对应(映射)
m[b]=a;
s.insert(a);
s.insert(b);
}
cin>>n;
for(i=0; i<n; i++)
{
string c;
cin>>c;
s1.insert(c);
}
for(auto it=s1.begin(); it!=s1.end(); it++)
{
if(s.find(*it)==s.end()||s1.find(m[*it])==s1.end())//对单身狗进行判断
s2.insert(*it);
}
cout<<s2.size()<<endl;
for(auto it=s2.begin(); it!=s2.end(); it++)//输出单身狗
{
if(it!=s2.begin())
cout<<" ";
cout<<*it;
}
return 0;
}
7-7 词典
你刚从滑铁卢搬到了一个大城市,这里的人们讲一种难以理解的外语方言。幸运的是,你有一本字典来帮助你理解它们。
输入格式:
输入第一行是正整数N和M,后面是N行字典条目(最多10000条),然后是M行要翻译的外语单词(最多10000个)。每一个字典条目都包含一个英语单词,后面跟着一个空格和一个外语单词。
输入中的每个单词都由最多10个小写字母组成。
输出格式:
输出翻译后的英文单词,每行一个单词。非词典中的外来词汇输出“eh”。
输入样例:
5 3
dog ogday
cat atcay
pig igpay
froot ootfray
loops oopslay
atcay
ittenkay
oopslay
输出样例:
cat
eh
loops
#include <bits/stdc++.h>
using namespace std;
map<string,string>dic;
int main()
{
int n,m;
cin>>n>>m;
int i;
for(i=0; i<n; i++)
{
string a,b;
cin>>a>>b;
dic[b]=a;
}
for(i=0; i<m; i++)
{
string x;
cin>>x;
if(dic[x]!="\0")
cout<<dic[x]<<endl;
else cout<<"eh"<<endl;
}
return 0;
}
7-8 这是二叉搜索树吗?
一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点,
- 其左子树中所有结点的键值小于该结点的键值;
- 其右子树中所有结点的键值大于等于该结点的键值;
- 其左右子树都是二叉搜索树。
所谓二叉搜索树的“镜像”,即将所有结点的左右子树对换位置后所得到的树。
给定一个整数键值序列,现请你编写程序,判断这是否是对一棵二叉搜索树或其镜像进行前序遍历的结果。
输入格式:
输入的第一行给出正整数 N(≤1000)。随后一行给出 N 个整数键值,其间以空格分隔。
输出格式:
如果输入序列是对一棵二叉搜索树或其镜像进行前序遍历的结果,则首先在一行中输出 YES
,然后在下一行输出该树后序遍历的结果。数字间有 1 个空格,一行的首尾不得有多余空格。若答案是否,则输出 NO
。
输入样例 1:
7
8 6 5 7 10 8 11
输出样例 1:
YES
5 7 6 8 11 10 8
输入样例 2:
7
8 10 11 8 6 7 5
输出样例 2:
YES
11 8 10 7 5 6 8
输入样例 3:
7
8 6 8 5 10 9 11
输出样例 3:
NO
#include <bits/stdc++.h>
using namespace std;
int pre[2000];
vector<int>rev;
int ismirror=0;
void solve(int root,int tail){
if(root>tail)return;
int i=root+1,j=tail;
if(!ismirror){
while(i<=tail&&pre[i]<pre[root])i++;
while(j>root&&pre[j]>=pre[root])j--;
}
else{
while(i<=tail&&pre[i]>=pre[root])i++;
while(j>root&&pre[j]<pre[root])j--;
}
solve(root+1,i-1);//如果不是二叉排序树,则两个指针i,j不相邻,则此处进入递归的两个区间的并元素数量一定小于区间元素数量减一
solve(j+1,tail);
rev.push_back(pre[root]);
}
int main()
{
int N;
cin>>N;
for(int i=0;i<N;i++){
cin>>pre[i];
}
solve(0,N-1);
if(rev.size()!=N){//可能是mirror,要再判断一次
rev.clear();
ismirror=1;
solve(0,N-1);
}
if(rev.size()!=N){
cout<<"NO"<<endl;
}
else{
cout<<"YES"<<endl;
for(int i=0;i<rev.size();i++){
if(i!=0)cout<<" ";
cout<<rev[i];
}
}
return 0;
}