【离散数学上机】T235,T236

T235题目:输入集合A和B,输出A到B上的所有单射函数。

问题描述

给定非空数字集合A和B,求出集合A到集合B上的所有单射函数。

输入格式

第一行输入m和n(空格间隔),分别为集合A和集合B中的元素个数;

第二行输入非空数字集合A,每个元素之间用空格间隔;

第三行输入非空数字集合B,每个元素之间用空格间隔;

输出格式

输出每一行为集合A到集合B的一个构成单射函数的二元关系,按二元关系的基数大小从小到大输出所有二元关系,相同基数的二元关系按序偶中元素的字典序排列。

样例输入

2 2

1 2

3 4

样例输出

{<1,3>,<2,4>}

{<1,4>,<2,3>}

在T234基础上,保证加入q集合中元素不重复即可,前者链接见下:

【xdoj-离散线上练习H】T234(C++)-CSDN博客

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

int main()
{
	//预处理:利用优先队列将集合中元素从小到大放进数组A,B中
	int m, n, cur;
	cin>>m>>n;
	priority_queue<int>pq;	
	vector<int>A(m);
	vector<int>B(n);
	for(int i=0; i<m; i++) 
	{
		cin>>cur; pq.push(cur);
	}
	for(int i=1; i<=m; i++) 
	{
		A[m-i] = pq.top(); pq.pop();		
	}
	for(int i=0; i<n; i++) 
	{
		cin>>cur; pq.push(cur);
	}
	for(int i=1; i<=n; i++) 
	{
		B[n-i] = pq.top(); pq.pop();		
	}
	
	//观察输出样例:每行输出均有A中全部元素,B对应元素每行只有一处变化
	vector<int>q(m);//q[i]携带了当前映射关系中A[i]对应的集合B中元素
	//为什么用递归:因为A中元素数量不确定,事实上,如果用for循环嵌套,那么for循环的数量为 m,这是不能在确定的代码中实现的
	auto dfs = [&](auto& dfs, int cnt) -> void
	{
		if(cnt == m)//递归终止条件
		{
			cout<<"{";
			for(int i=0; i<m; i++)
			{
				cout<<"<"<<A[i]<<","<<q[i]<<">";				
				if(i == m-1) cout<<"}"<<endl;
				else cout<<",";
			}
			return;			
		}
		else{//继续递归
			for(int i=0; i<n; i++)
			{
				//保证q中的元素不重复
				int k=0;
				for( ; k<cnt; k++)
				{
					if(q[k] == B[i]) break;
				}	
				if(k == cnt)				
				{
					q[cnt] = B[i];
					dfs(dfs, cnt+1);
				}			
			}			
			return;
		}
	};
	dfs(dfs, 0);
	return 0;	
}

T236题目:输入集合A和B,输出A到B上的所有满射函数。

只需将dfs函数替换成如下形式

cpp 复制代码
auto dfs = [&](auto& dfs, int cnt) -> void
	{
		if(cnt == m)//递归终止条件
		{
			set<int>st;
			for(int i=0; i<m; i++)
			{
				st.insert(q[i]);
			}
			if(st.size() == n)
			{
				cout<<"{";
				for(int i=0; i<m; i++)
				{
					cout<<"<"<<A[i]<<","<<q[i]<<">";				
					if(i == m-1) cout<<"}"<<endl;
					else cout<<",";
				}
			}
			
			return;			
		}
		else{//继续递归
			for(int i=0; i<n; i++)
			{
				q[cnt] = B[i];
				dfs(dfs, cnt+1);						
			}			
			return;
		}
	};

T237题目:输入集合A和B,输出A到B上的所有双射函数。

将dfs换成这个就成

cpp 复制代码
auto dfs = [&](auto& dfs, int cnt) -> void
	{
		if(cnt == m)//递归终止条件
		{
			set<int>st;
			for(int i=0; i<m; i++)
			{
				st.insert(q[i]);
			}
			if(st.size() == n)
			{
				cout<<"{";
				for(int i=0; i<m; i++)
				{
					cout<<"<"<<A[i]<<","<<q[i]<<">";				
					if(i == m-1) cout<<"}"<<endl;
					else cout<<",";
				}
			}
			
			return;			
		}
		else{//继续递归
			for(int i=0; i<n; i++)
			{
				//保证q中的元素不重复
				int k=0;
				for( ; k<cnt; k++)
				{
					if(q[k] == B[i]) break;
				}	
				if(k == cnt)				
				{
					q[cnt] = B[i];
					dfs(dfs, cnt+1);
				}							
			}			
			return;
		}
	};
相关推荐
KJ_BioMed43 分钟前
从PDB到高亲和力分子:De novo生成式计算化学Pipeline剖析
算法·生物医药·生物科研·科研干货·化合物设计
一个王同学2 小时前
从零到一 | CV转多模态大模型 | week17 | LLM 推理优化 & vLLM 详解
人工智能·深度学习·算法·机器学习·计算机视觉·vllm
旖-旎3 小时前
《LeetCode 53 最大子数组和 || LeetCode 918 环形子数组的最大和》
c++·算法·leetcode·动态规划
变量未定义~3 小时前
单调栈+倍增思想 皇家守卫【算法赛】、单调队列 附近最小
算法
QN1幻化引擎3 小时前
给 AI 做一次「意识体检」——基于 QN1 幻化引擎的灵鉴意识识别框架与 DalinX V5 实测
大数据·数据结构·人工智能·算法·架构
拂拉氏3 小时前
【知识讲解】 AVL树从基本成员的介绍到核心接口的实现(插入、判断、删除等等)
数据结构·算法·avl树
可靠的仙人掌4 小时前
SAC(Soft Actor-Critic)算法底座
开发语言·算法·php
c238564 小时前
《动态规划:从“傻傻穷举”到“过目不忘”的修仙之路》
c++·算法·动态规划
海石5 小时前
单调栈复健,顺便,牺牲一下吧,空间复杂度!一切献给AC
算法·leetcode
海石5 小时前
JS击败94%,Hard题想不到动态规划,那就用数组和栈试试
算法·leetcode