离散重点背诵

博客包含多个离散数学相关的编程问题,如用位串表示法判断集合包含关系、确定传递闭包下可排名的牛数量、判断函数是否为双射、找出代数系统的幺元和逆元、建图并输出关系矩阵等,给出了各问题的输入输出要求。

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

1、集合的包含
Time Limit: 1000 ms Memory Limit: 65536 KiB

Problem Description
已知含n个元素的集合的子集A和B,用位串表示法判断是否有A⊆B。

Input
多组测试数据,每组测试数据第1行输入正整数n(1 <= n <= 100),表示集合元素 个数,第2行输入位串表示法形式的集合A,第3行输入位串表示法形式的集合B。

Output
对于每组测试数据,若A⊆B则输出yes,反之则输出no。

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int i, n;
    while(~scanf("%d", &n))
    {
        int flag = 1;
        int a[110];
        int b[110];
        for(i=0; i<n; i++)
        {
            scanf("%d", &a[i]);
        }
        for(i=0; i<n; i++)
        {
            scanf("%d", &b[i]);
        }
        for(i=0; i<n; i++)
        {
            if(!b[i])
            {
                if(a[i])
                {
                    flag = 0;
                    break;
                }
            }
        }
        if(flag) printf("yes\n");
        else printf("no\n");
    }
    return 0;
}

2、
传递闭包
Time Limit: 1000 ms Memory Limit: 65536 KiB

Problem Description
已知有n头牛,m次战斗关系,询问最终可以确定排名的牛的数量。

Input
多组测试数据,对于每组测试数据,第1行输入两个整数n(1 <= n <= 100)和m(0 <= m <= 4950),分别表示有n头牛和m次战斗关系,之后m行每行输入两个正整数x和y表示编号为x的牛可以战胜编号为y的牛,数据保证合法,询问可以确定排名的牛的数量。

Output
对于每组测试数据,输出整数ans,表示可以确定排名的牛的数量。


#include<stdio.h>
#include<string.h>
int a[110][110];
void warshell(int n)
{
    int k, i, j;
    for(i=1; i<=n; i++)
    {
        for(j=1; j<=n; j++)
        {
            if(a[j][i])
            {
                for(k=1; k<=n; k++)
                {
                    a[j][k] = a[j][k] + a[i][k];
                    if(a[j][k] >= 1)
                        a[j][k] = 1;
                }
            }
        }
    }
}
int main()
{
    int m, n, x, y, i, j, ans, flag[110];
    while(~scanf("%d %d", &n, &m))
    {
        ans = 0;
        memset(a, 0, sizeof(a));
        memset(flag, 1, sizeof(flag));  
        while(m--)
        {
            scanf("%d %d", &x, &y);
            a[x][y] = 1;
        }
        warshell(n);
        for(j=1; j<=n; j++)
        {
    
            for(i=1; i<=n; i++)
            {
                if(i == j)
                {
                    if(a[i][j])
                    {
                        flag[j] = 0; 
                        break;
                    }
                }
                else if(!a[i][j])
                {
                    if(!a[j][i])  
                    {
                        flag[j] = 0;
                        break;
                    }
                }
            }
            if(flag[j]) 
            {
                ans++;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}

3、
离散题目11
Time Limit: 1000 ms Memory Limit: 65536 KiB

Problem Description
给定一个数学函数写一个程序来确定该函数是否是双射的

Input
多组输入。 第一行输入三个整数n,m,k,分别表示集合a中的元素个数,集合b中的元素个数,集合a到b的映射个数。 第二行输入n个数,代表集合a中的元素。 第三行输入m个数,代表集合b中的元素。接下来k行,每行两个数,代表集合a中的元素x和x在集合b中的像y。

Output
每组数据输出一行,若F为a到b的双射,输出"YES", 否则输出"NO"。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
    int n,m,k,i,f,x,y;
    int a[1001],b[1001],c[1001],d[1001];
    while(~scanf("%d%d%d",&n,&m,&k))
    {
        f=0;
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(c,0,sizeof(c));
        memset(d,0,sizeof(d));
        for(i=0;i<n;i++)
        {
            scanf("%d",&b[i]);
        }
        for(i=0;i<m;i++)
        {
            scanf("%d",&d[i]);
        }
        for(i=0;i<k;i++)
        {
            scanf("%d%d",&x,&y);
            a[x]++;
            c[y]++;
        }
        for(i=0;i<n;i++)
        {
            if(a[b[i]]>1)
            {
                f=1;
                break;
            }
        }
        for(i=0;i<m;i++)
        {
            if(c[d[i]]<1)
            {
                f=1;
                break;
            }
        }
        if(f==1)
        {
            printf("NO\n");
        }
        else printf("YES\n");
    }
    return 0;
}


/***************************************************
User name: jk180410付和健
Result: Accepted
Take time: 0ms
Take Memory: 156KB
Submit time: 2019-04-18 10:39:49
****************************************************/

4、
离散题目11
Time Limit: 1000 ms Memory Limit: 65536 KiB

Problem Description
给定一个数学函数写一个程序来确定该函数是否是双射的

Input
多组输入。 第一行输入三个整数n,m,k,分别表示集合a中的元素个数,集合b中的元素个数,集合a到b的映射个数。 第二行输入n个数,代表集合a中的元素。 第三行输入m个数,代表集合b中的元素。接下来k行,每行两个数,代表集合a中的元素x和x在集合b中的像y。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
    int n,m,k,i,f,x,y;
    int a[1001],b[1001],c[1001],d[1001];
    while(~scanf("%d%d%d",&n,&m,&k))
    {
        f=0;
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(c,0,sizeof(c));
        memset(d,0,sizeof(d));
        for(i=0;i<n;i++)
        {
            scanf("%d",&b[i]);
        }
        for(i=0;i<m;i++)
        {
            scanf("%d",&d[i]);
        }
        for(i=0;i<k;i++)
        {
            scanf("%d%d",&x,&y);
            a[x]++;
            c[y]++;
        }
        for(i=0;i<n;i++)
        {
            if(a[b[i]]>1)
            {
                f=1;
                break;
            }
        }
        for(i=0;i<m;i++)
        {
            if(c[d[i]]<1)
            {
                f=1;
                break;
            }
        }
        if(f==1)
        {
            printf("NO\n");
        }
        else printf("YES\n");
    }
    return 0;
}

5、
找出幺元和逆元
Time Limit: 1000 ms Memory Limit: 65536 KiB

Problem Description
设I为整数集,定义二元运算的运算为ab = a+b-k,其中k为输入的整数,a,b是集合I内的数,求代数系统V=< I, * >幺元和逆元。

Input
多组输入,每次输入两个正整数k(0<=k<100)和q(0<=q<100),k为题目中的k,q代表q次询问,之后输入q个整数x(0<=x<100).

Output
第一行输出幺元
接下来输出q行,为对应的x的逆元。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int k,q,x;
    while(scanf("%d %d",&k,&q)!=EOF)
    {
        printf("%d\n",k);
        while(q--)
        {
            scanf("%d",&x);
            printf("%d\n",2*k-x);
        }
    }
    return 0;
}

6、
建图
Time Limit: 1000 ms Memory Limit: 65536 KiB

Problem Description
编程使得程序可以接受一个图的点边作为输入,然后显示出这个图。

Input
多组测试数据,对于每组测试数据,第一行输入正整数n(1 <= n <= 1000)和m,之后m行输入正整数x、y,表示在点x和点y之间存在有向边相连。

Output
对于每组测试数据,输出图的关系矩阵。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MA 1010
int G[MA][MA];

int main()
{
    int n, m;
    while(~scanf("%d %d", &n, &m))
    {
        int x, y;
        int i, j;
        memset(G, 0, sizeof(G));
        while(m--)
        {
            scanf("%d %d", &x, &y);
            G[x][y] = 1;
        }
        for(i=1; i<=n; i++)
        {
            for(j=1; j<=n-1; j++)
            {
                printf("%d ", G[i][j]);
            }
            printf("%d\n", G[i][j]);
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值