2024年团体程序设计天梯赛

L2-049 鱼与熊掌

在这里插入图片描述
《孟子 · 告子上》有名言:“鱼,我所欲也,熊掌,亦我所欲也;二者不可得兼,舍鱼而取熊掌者也。”但这世界上还是有一些人可以做到鱼与熊掌兼得的。
给定 n n n 个人对 m m m 种物品的拥有关系。对其中任意一对物品种类(例如“鱼与熊掌”),请你统计有多少人能够兼得?

输入格式:

输入首先在第一行给出 2 个正整数,分别是: n n n ≤ 1 0 5 ≤10^5 105 )为总人数(所有人从 1 到 n n n 编号)、 m m m 2 ≤ m ≤ 1 0 5 2≤m≤10^5 2m105 )为物品种类的总数(所有物品种类从 1 到 m 编号)。
随后 n n n 行,第 i i i 行( 1 ≤ i ≤ n 1≤i≤n 1in)给出编号为 i i i 的人所拥有的物品种类清单,格式为:

K M[1] M[2] ... M[K]

其中 K ≤ 1 0 3 ≤10^3 103 )是该人拥有的物品种类数量,后面的 M[*] 是物品种类的编号。题目保证每个人的物品种类清单中都没有重复给出的种类。
最后是查询信息:首先在一行中给出查询总量 Q Q Q ≤ 100 ≤100 100),随后 Q Q Q 行,每行给出一对物品种类编号,其间以空格分隔。题目保证物品种类编号都是合法存在的。

输出格式:

对每一次查询,在一行中输出两种物品兼得的人数。

输入样例:
4 8
3 4 1 8
4 7 1 8 4
5 6 5 1 2 3
4 3 2 4 8
3
2 3
7 6
8 4
输出样例:
2
0
3
#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int,int> PII;

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n,m;cin>>n>>m;
	vector<unordered_set<int>> g(n);
	
	for(int i=0;i<n;i++)
	{
		int k;cin>>k;
		while(k--)
		{
			int x;cin>>x;
			g[i].insert(x);
		}
	}
	
	int q;cin>>q;
	while(q--)
	{
		int a,b;cin>>a>>b;
		int res=0;
		for(int i=0;i<n;i++)
			if(g[i].count(a)&&g[i].count(b))
				res++;
		cout<<res<<"\n";
	}
	
    return 0;
}

L2-050 懂蛇语

在这里插入图片描述
在《一年一度喜剧大赛》第二季中有一部作品叫《警察和我之蛇我其谁》,其中“毒蛇帮”内部用了一种加密语言,称为“蛇语”。蛇语的规则是,在说一句话 A 时,首先提取 A 的每个字的首字母,然后把整句话替换为另一句话 B,B 中每个字的首字母与 A 中提取出的字母依次相同。例如二当家说“九点下班哈”,对应首字母缩写是 JDXBH,他们解释为实际想说的是“京东新百货”……
本题就请你写一个蛇语的自动翻译工具,将输入的蛇语转换为实际要表达的句子。

输入格式:

输入第一行给出一个正整数 N N N ≤ 1 0 5 ≤10^5 105 ),为蛇语词典中句子的个数。随后 N N N 行,每行用汉语拼音给出一句话。每句话由小写英文字母和空格组成,每个字的拼音由不超过 6 个小写英文字母组成,两个字的拼音之间用空格分隔。题目保证每句话总长度不超过 50 个字符,用回车结尾。注意:回车不算句中字符。
随后在一行中给出一个正整数 M M M ≤ 1 0 3 ≤10^3 103 ),为查询次数。后面跟 M M M 行,每行用汉语拼音给出需要查询的一句话,格式同上。

输出格式:

对每一句查询,在一行中输出其对应的句子。如果句子不唯一,则按整句的字母序输出,句子间用 | 分隔。如果查不到,则将输入的句子原样输出。
注意:输出句子时,必须保持句中所有字符不变,包括空格。

输入样例:
8
yong yuan de shen
yong yuan de she
jing dong xin bai huo
she yu wo ye hui shuo yi dian dian
liang wei bu yao chong dong
yi  dian dian
ni hui shuo she yu a
yong yuan de sha
7
jiu dian xia ban ha
shao ye wu ya he shui you dian duo
liu wan bu yao ci dao
ni hai shi su yan a
yao diao deng
sha ye ting bu jian
y y d s
输出样例:
jing dong xin bai huo
she yu wo ye hui shuo yi dian dian
liang wei bu yao chong dong
ni hui shuo she yu a
yi  dian dian
sha ye ting bu jian
yong yuan de sha|yong yuan de she|yong yuan de shen
#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int,int> PII;

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;cin>>n;
	map<string,multiset<string>> mp;
	
	string s;
	getline(cin,s);
	for(int i=0;i<n;i++)
	{
		getline(cin,s);
		stringstream ss(s);
		string str,word;
		while(ss>>word) str+=word[0];
		mp[str].insert(s);
	}
	
	int m;cin>>m;
	getline(cin,s);
	for(int i=0;i<m;i++)
	{
		getline(cin,s);
		stringstream ss(s);
		string str,word;
		while(ss>>word) str+=word[0];

		if(!mp.count(str)) cout<<s;
		else
		{
			bool ok=false;
			for(auto c:mp[str])
			{
				if(ok) cout<<"|";
				cout<<c;
				ok=true;
			}
		}
		cout<<"\n";
	}
	
    return 0;
}

L2-051 满树的遍历

一棵“ k k k 阶满树”是指树中所有非叶结点的度都是 k k k 的树。给定一棵树,你需要判断其是否为 k k k 阶满树,并输出其前序遍历序列。

注:树中结点的度是其拥有的子树的个数,而树的度是树内各结点的度的最大值。

输入格式:

输入首先在第一行给出一个正整数 n n n ≤ 1 0 5 ≤10^5 105 ),是树中结点的个数。于是设所有结点从 1 1 1 n n n 编号。
随后 n n n 行,第 i i i 行( 1 ≤ i ≤ n 1≤i≤n 1in)给出第 i i i 个结点的父结点编号。根结点没有父结点,则对应的父结点编号为 0。题目保证给出的是一棵合法多叉树,只有唯一根结点。

输出格式:

首先在一行中输出该树的度。如果输入的树是 k k k 阶满树,则加 1 个空格后输出 yes,否则输出 no。最后在第二行输出该树的前序遍历序列,数字间以 1 个空格分隔,行首尾不得有多余空格。
注意:兄弟结点按编号升序访问。

输入样例 1:
7
6
5
5
6
6
0
5
输出样例 1:
3 yes
6 1 4 5 2 3 7
输入样例 2:
7
6
5
5
6
6
0
4
输出样例 2:
3 no
6 1 4 7 5 2 3
#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int,int> PII;

vector<int> res;

void dfs(int u,vector<vector<int>> &g)
{
	for(int c:g[u])
	{
		res.push_back(c);
		dfs(c,g);
	}
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;cin>>n;
	vector<vector<int>> g(n+1);
	vector<int> d(n);
	for(int i=1;i<=n;i++)
	{
		int x;cin>>x;
		g[x].push_back(i);
		d[x]++;
	}
	
	int k=0;
	for(int i=1;i<n;i++)
		if(d[i]>k) 
			k=d[i];
			
	bool ok=0;
	for(int i=1;i<n;i++)
		if(d[i]!=k&&d[i]!=0)
		{
			ok=1;
			break;
		}
	
	cout<<k<<" ";
	if(ok) cout<<"no\n";
	else cout<<"yes\n";
	
	dfs(0,g);
	
	cout<<res[0];
	for(int i=1;i<res.size();i++)
		cout<<" "<<res[i];
	
    return 0;
}
  • 10
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wa_Automata

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值