SDUT数据结构PTA 查找表

7-1 电话聊天狂人

给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人。

输入格式:

输入首先给出正整数N(≤1e5),为通话记录条数。随后N行,每行给出一条通话记录。简单起见,这里只列出拨出方和接收方的11位数字构成的手机号码,其中以空格分隔。

输出格式

在一行中给出聊天狂人的手机号码及其通话次数,其间以空格分隔。如果这样的人不唯一,则输出狂人中最小的号码及其通话次数,并且附加给出并列狂人的人数。

#include<bits/stdc++.h>
using namespace std;
map<string,int> mp;
map<string,int>::iterator it;
int main()
{
    string s1,s2;
    int n,i,j;
    cin>>n;
    int maxn=0,cnt=0;
    for(i=0;i<n;i++)
    {
        cin>>s1>>s2;
        mp[s1]++;
        mp[s2]++;
    }
    string id;
    for(it=mp.begin();it!=mp.end();it++)
    {
        if(it->second>maxn){
            maxn=it->second;
            id=it->first;
            cnt=1;
        }
        else if(it->second==maxn){
            cnt++;
        }
    }
    cout<<id<<" "<<maxn;
    if(cnt>1) cout<<" "<<cnt;
}

7-2 两个有序序列的中位数

在这里插入图片描述

输入格式:

输入分三行。第一行给出序列的公共长度N(0<N≤100000),随后每行输入一个序列的信息,即N个非降序排列的整数。数字用空格间隔。

输出格式:

在一行中输出两个输入序列的并集序列的中位数。

#include<bits/stdc++.h>
using namespace std;
int main()
{
    vector<int> q;
    int n,i,j;
    cin >>n;
    for(i=0;i<n*2;i++)
    {cin>>j;q.push_back(j);}
    sort(q.begin(),q.end());
    cout<<q[n-1];
}

7-3 词频统计

请编写程序,对一段英文文本,统计其中所有不同单词的个数,以及词频最大的前10%的单词。

所谓“单词”,是指由不超过80个单词字符组成的连续字符串,但长度超过15的单词将只截取保留前15个单词字符。而合法的“单词字符”为大小写字母、数字和下划线,其它字符均认为是单词分隔符。

输入格式:

输入给出一段非空文本,最后以符号#结尾。输入保证存在至少10个不同的单词。

输出格式:

在第一行中输出文本中所有不同单词的个数。注意“单词”不区分英文大小写,例如“PAT”和“pat”被认为是同一个单词。

随后按照词频递减的顺序,按照 词频:单词 的格式输出词频最大的前10%的单词。若有并列,则按递增字典序输出。

#include<bits/stdc++.h>
using namespace std;
typedef pair<string,int> pl;
map<string,int> m1;
vector<pl> q;
int cmp(pl a,pl b)
{
	if(a.second==b.second)
	return a.first<b.first;
	else return a.second>b.second;
}
int main()
{
	char c;
	string s;
	while(scanf("%c",&c)&&c!='#')
	{
		if((c>='0'&&c<='9')||(c>='A'&&c<='Z')||(c>='a'&&c<='z')||c=='_')
		{
			if(c>='A'&&c<='Z')c=c-'A'+'a';
			if(s.size()<15)s+=c;
		}
		else if(s.size()>0)
		{
			m1[s]++;
			s.clear();
		}
	}
	for(auto it=m1.begin();it!=m1.end();it++)
	{
		q.push_back({it->first,it->second});
	}
	sort(q.begin(),q.end(),cmp);
	cout<<q.size()<<endl;
	for(int i=0;i<q.size()/10;i++)
	{
		cout<<q[i].second<<":"<<q[i].first<<endl;
	}
}

7-4 集合相似度

在这里插入图片描述

输入格式:

输入第一行给出一个正整数 n(≤50),是集合的个数。随后 n 行,每行对应一个集合。每个集合首先给出一个正整数 m(≤1e4 ),是集合中元素的个数;然后跟 m 个 [0,1e9 ] 区间内的整数。

之后一行给出一个正整数 k(≤2000),随后 k 行,每行对应一对需要计算相似度的集合的编号(集合从 1 到 n 编号)。数字间以空格分隔。

输出格式

对每一对需要计算的集合,在一行中输出它们的相似度,为保留小数点后 2 位的百分比数字。

#include<bits/stdc++.h>
using namespace std;
const int N=55;
set<int> s[N];
int main()
{
    int n,m,i,j;
    cin>>n;
    for(i=1;i<=n;i++)
    {
        cin>>m;
        while(m--)
        {
            cin>>j;
            s[i].insert(j);
        }
    }
    int k,a,b;
    cin>>k;
    while(k--)
    {
        int num=0;
        cin>>a>>b;
        for(auto it : s[a])
        {
            if(s[b].find(it)!=s[b].end())
            {
                num++;
            }
        }
    
    j=s[a].size()+s[b].size()-num;
    double d=0;
    d=1.0*num/j;
    printf("%.2f%%\n",d*100);
    }
}

7-5 悄悄关注

新浪微博上有个“悄悄关注”,一个用户悄悄关注的人,不出现在这个用户的关注列表上,但系统会推送其悄悄关注的人发表的微博给该用户。现在我们来做一回网络侦探,根据某人的关注列表和其对其他用户的点赞情况,扒出有可能被其悄悄关注的人。

输入格式:

输入首先在第一行给出某用户的关注列表

输出格式:

我们认为被该用户点赞次数大于其点赞平均数、且不在其关注列表上的人,很可能是其悄悄关注的人。根据这个假设,请你按用户ID字母序的升序输出可能是其悄悄关注的人,每行1个ID。如果其实并没有这样的人,则输出“Bing Mei You”。

#include <bits/stdc++.h>
using namespace std;
typedef pair<int,string> pl;
bool cmp(pl a, pl b) {
    return a.second < b.second;
}

int main() {
    int n, m, i, j;
    double ave, sum = 0;
    cin >> n;
    vector<string> t(n); // 初始化大小为 n 的 vector
    for (i = 0; i < n; i++)
        cin >> t[i];
    cin >> m;
    vector<pair<int, string>> q(m);
    for (i = 0; i < m; i++) {
        cin >> q[i].second >> q[i].first;
        sum += q[i].first;
    }
    ave = sum / m;
    // 使用比较函数进行排序
    sort(q.begin(), q.end(), cmp);
    bool flag = true; // 定义并初始化 flag
    for (i = 0; i < m; i++) {
        if (q[i].first > ave) {
            if (find(t.begin(), t.end(), q[i].second) == t.end()) { // 使用 find 函数检查元素是否在 vector 中
                cout << q[i].second << endl;
                flag = false;
            }
        }
    }
    if (flag) cout << "Bing Mei You";
    return 0;
}

7-6 这是二叉搜索树吗?

一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点,

其左子树中所有结点的键值小于该结点的键值;
其右子树中所有结点的键值大于等于该结点的键值;
其左右子树都是二叉搜索树。
所谓二叉搜索树的“镜像”,即将所有结点的左右子树对换位置后所得到的树。

给定一个整数键值序列,现请你编写程序,判断这是否是对一棵二叉搜索树或其镜像进行前序遍历的结果。

输入格式:

输入的第一行给出正整数 N(≤1000)。随后一行给出 N 个整数键值,其间以空格分隔。

输出格式:

如果输入序列是对一棵二叉搜索树或其镜像进行前序遍历的结果,则首先在一行中输出 YES ,然后在下一行输出该树后序遍历的结果。数字间有 1 个空格,一行的首尾不得有多余空格。若答案是否,则输出 NO。

#include<bits/stdc++.h>
using namespace std;
vector<int> tree;
int n,flag=0;//flag 标记此时构建树是否为镜像
int a[1005];//前序遍历结果
void creat(int root,int last){//构建树的根节点信息以及子结点的范围
	if(root>last) return ;
	int left=root+1;//右子树范围的左端点
	int right = last;//左子树范围的右端点
	if(!flag){
		while(left<=last&&a[left]<a[root]) ++left;//找到右子树第一个结点
		while(right>root&&a[right]>=a[root]) --right;//找到左子树最后一个结点
	}
	else{
		while(left<=last&&a[left]>=a[root]) ++left;
		while(right>root&&a[right]<a[root]) --right;
	}
	if(right!=(left-1)) return ;//左右点之间应当相邻
	creat(root+1,right);
	creat(left,last);
	tree.push_back(a[root]);//插入结点
}

int main(){
	cin >> n;
	for(int i = 1;i<=n;++i) scanf("%d",&a[i]);
	creat(1,n);
	if(tree.size()!=n){//二叉搜索树建树失败,构建镜像树
		flag = 1;
		tree.clear();
		creat(1,n);
	}
	if(tree.size()==n){//建树成功,输出
		cout <<"YES"<<endl;
		for(int i = 0;i<n-1;++i) cout << tree[i]<<" ";
		cout << tree[n-1]<<endl;
	}
	else cout << "NO"<<endl;
	return 0;
}

7-7 单身狗

“单身狗”是中文对于单身人士的一种爱称。本题请你从上万人的大型派对中找出落单的客人,以便给予特殊关爱。

输入格式:

输入第一行给出一个正整数 N(≤50000),是已知夫妻/伴侣的对数;随后 N 行,每行给出一对夫妻/伴侣——为方便起见,每人对应一个 ID 号,为 5 位数字(从 00000 到 99999),ID 间以空格分隔;之后给出一个正整数 M(≤10000),为参加派对的总人数;随后一行给出这 M 位客人的 ID,以空格分隔。题目保证无人重婚或脚踩两条船。

输出格式:

首先第一行输出落单客人的总人数;随后第二行按 ID 递增顺序列出落单的客人。ID 间用 1 个空格分隔,行的首尾不得有多余空格。

#include<bits/stdc++.h>
using namespace std;
map<string,string> mp1;
map<string,int> mp2;
vector<string> v1;
vector<string> v2;
int main()
{
	int n,i,j;
	string s1,s2,s;
	cin>>n;
	for(i=0;i<n;i++)
	{
		cin>>s1>>s2;
		mp1[s1]=s2;
		mp1[s2]=s1;
		mp2[s1]=1;
		mp2[s2]=1;
	}
	cin>>j;
	for(i=0;i<j;i++)
	{
		cin>>s;
		v1.push_back(s);
		mp2[s]++;
	}
	for(auto it : v1)
	{
		if(mp2[it]==2&&mp2[mp1[it]]==2)continue;
		v2.push_back(it);
	}
	sort(v2.begin(),v2.end());
	int cnt=v2.size();
	for(i=0;i<cnt;i++)
	{
		cout<< v2[i]<<" ";
	}
 } 

7-8 二叉搜索树

对于一个无穷的满二叉排序树(如图),节点的编号是1,2,3,…。对于一棵树根为X的子树,沿着左节点一直往下到最后一层,可以获得该子树编号最小的节点;沿着右节点一直往下到最后一层,可以获得该子树编号最大的节点。现在给出的问题是“在一棵树根为X的子树中,节点的最小编号和最大编号是什么?”。请你给出答案。

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    cin>>n;
    while(n--)
    {
        int x;
        cin>>x;
        int t=x;
        int b=1;
        while(x%2==0){
            x/=2;
            b*=2;
        }
        b--;
        cout<<t-b<<" "<<t+b<<endl;
    }
}

7-9 词典

你刚从滑铁卢搬到了一个大城市,这里的人们讲一种难以理解的外语方言。幸运的是,你有一本字典来帮助你理解它们。

输入格式:

输入第一行是正整数N和M,后面是N行字典条目(最多10000条),然后是M行要翻译的外语单词(最多10000个)。每一个字典条目都包含一个英语单词,后面跟着一个空格和一个外语单词。
输入中的每个单词都由最多10个小写字母组成。

输出格式:

输出翻译后的英文单词,每行一个单词。非词典中的外来词汇输出“eh”。

#include<bits/stdc++.h>
using namespace std;
map<string,string> p;
int main()
{
	int n,m,i;
	string s1,s2,s;
	cin>>n>>m;
	for(i=0;i<n;i++)
	{
		cin >>s1>>s2;
		p[s2]=s1;
	}
	while(m--)
	{
		cin>>s;
		if(p.find(s)!=p.end())cout<<p[s]<<endl;
		else cout<<"eh\n";
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值