离散题目10 判断满射

本文介绍了一种通过编程方式判断给定数学函数是否为满射的方法。具体来说,该程序接收两个有限集合A和B及它们之间的关系F作为输入,并确定F是否满足满射条件,即B中的每个元素在A中至少有一个对应的原像。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem Description

给定一个数学函数F和两个集合A,B,写一个程序来确定函数是满射。 如果每个可能的像至少有一个变量映射其上(即像集合B中的每个元素在A中都有一个或一个以上的原像),或者说值域任何元素都有至少有一个变量与之对应,那这个映射就叫做满射。

Input

多组输入直到文件结束,对于每组输入,第一行先输入一个n(A集合里的元素个数),m(B集合里的元素个数),k(F数学函数关系的条数)。

0 < n,m < 10000, 0 < k < n;

第二行输入有n个元素,分别为a1到an;

第三行输入有m个元素,分别为b1到bn;

接下来输入有k行,分别为集合A到B的关系

Output

(一组答案占一行)

当满足满射关系时输出Yes。

不满足关系时输出No。

Example Input

5 3 5
1 3 5 7 8
2 5 6
1 2
3 6
5 5
7 2
8 6

Example Output

Yes
代码如下

#include<stdio.h>
int main()
{
    int n , m ,k,i, j,num,flat,flag ;
    int a[10010],b[10010];
    int c[10010],d[10010];
    while(scanf("%d %d %d",&n,&m,&k)!=EOF)
    {
        for(i = 0;i<n;i++)
            scanf("%d",&a[i]);
        for(j = 0;j<m;j++)
            scanf("%d",&b[j]);
        for(i = 0;i<k;i++)
            scanf("%d %d",&c[i],&d[i]);
            num = 0 ; flag = 0;
        for(i = 0;i<m;i++)
        {
            for(j = 0;j<k;j++)
            {
                if(b[i]==d[j])
                {
                    num++;
                    break;
                }
            }
        }
        if(num==m)
            flag = 1;
        num = 0;flat = 0;
        for(i = 0;i<n;i++)
        {
            for(j = 0;j<k;j++)
            {
                if(a[i]==c[j])
                {
                    num++;
                    break;
                }
            }
        }
        if(num<n||num==n)
            flat = 1;
        if(flag&&flat)
            printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

### 单射与满射的定义 #### 单射 (Injection) 单射是指对于任意两个不同的输入 \(a\) 和 \(b\),它们对应的输出也不同。换句话说,在函数 \(f : A \to B\) 中,如果满足条件: \[ \forall a_1, a_2 \in A,\ f(a_1) = f(a_2) \implies a_1 = a_2, \] 则该函数被称为单射[^1]。 #### 满射 (Surjection) 满射是指目标集合 \(B\) 的每一个元素都至少有一个来自源集合 \(A\) 的元素与其相对应。也就是说,在函数 \(f : A \to B\) 中,如果满足条件: \[ \forall b \in B,\ \exists a \in A \text{ such that } f(a) = b, \] 则该函数被称为满射[^3]。 --- ### 单射与满射的区别 | **特性** | **单射** | **满射** | |----------------|---------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------| | 定义 | 输入的不同导致输出的不同 | 输出覆盖整个目标集合 | | 数学表达 | 如果 \(f(x_1) = f(x_2)\),那么必有 \(x_1 = x_2\) | 对于任何 \(y \in B\),存在某个 \(x \in A\) 使得 \(f(x) = y\) | | 集合间关系 | 不允许重复映射 | 要求每个目标都有原像 | --- ### 示例分析 #### 单射示例 考虑函数 \(f: \mathbb{Z} \to \mathbb{Z}\),其中 \(f(x) = 2x\)。因为当 \(x_1 \neq x_2\) 时,\(f(x_1) \neq f(x_2)\),所以这是一个单射。 ```python def is_injective(f_values): return len(set(f_values)) == len(f_values) # 测试数据 input_data = [1, 2, 3] output_data = list(map(lambda x: 2 * x, input_data)) print(is_injective(output_data)) # True 表明这是单射 ``` #### 满射示例 考虑函数 \(g: \mathbb{N} \to \mathbb{N}\),其中 \(g(x) = x - 1\) (假设自然数从零开始)。由于每个自然数都可以通过加一得到其前驱,因此这是一个满射。 ```python def is_surjective(domain, codomain, g_func): image_set = set(g_func(x) for x in domain) return image_set == set(codomain) # 测试数据 domain = range(5) # {0, 1, 2, 3, 4} codomain = range(-1, 4) # {-1, 0, 1, 2, 3} g_func = lambda x: x - 1 print(is_surjective(domain, codomain, g_func)) # True 表明这是满射 ``` --- ### 结论 单射强调的是“一对一”的映射关系;而满射关注的是目标集合中的所有元素都被映射到。两者的核心区别在于前者不允许重复映射,后者要求完全覆盖目标集合。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值