离散题目16

离散题目16

Time Limit: 1000MS  Memory Limit: 65536KB
Problem Description

给出集合A,以及集合A上的关系R,求关系R的自反闭包。

Input

首先输入t,表示有t组数据.    

每组数据第一行输入n,表示A中有n个数据,接下来一行输入n个数,(4 <= n < 100, 0 < Ai < 100)

第二行输入m,代表R中有m对关系(0 < m < 100)

接下来m行每行输入x,y代表< x,y >这对关系.(从小到大给出关系,如果x相同,按y排列)

Output

输出题目要求的关系集合,每行输出一对关系,输出顺序按照中的x大小非递减排列,假如x相等按照y大小非递减排列.

每组数据末尾额外输出一行空行。

Example Input
1
5
1 2 3 4 5
6
1 1
1 2
2 3
3 3
4 5
5 1
Example Output
1 1
1 2
2 2
2 3
3 3
4 4
4 5
5 1
5 5
Hint
Author

Johsnows


知道自反闭包的定义,知道排序,注意最后的每组数据后有空行;

比如R={(a,b),(b,b),(b,d)},那么R的自反闭包就是
{(a,b),(b,b),(b,d)}∪{(a,a),(b,b),(d,d)}={(a,b),(b,b),(b,d),(a,a),(d,d)}
 

一开始,按照书上的求法,我们应该并上集合中元素的 全部自反序偶,但是 提交结果为WA;

以下为WA代码

#include <bits/stdc++.h>

using namespace std;

set<int> s;
int a[10001][10001];
int main()
{
    int m, n, k;
    cin>>k;
    while(k--)
    {
        int x,y;
        cin>>m;
        for(int i = 0; i < m; i++)
        {
            cin>>x;
            s.insert(x);
        }

        cin>>n;

        for(int i = 0; i < n; i++)
        {
            cin>>x>>y;
            a[x][y] = 1;
        }

        set<int>::iterator it1, it2;
        for(it1 = s.begin(); it1 != s.end(); it1++)
            for(it2 = s.begin(); it2 != s.end(); it2++)
            {
                if(*it1 == *it2)//此处,只要x,y相等便输出,即并上所有自反序偶;
                    cout<<*it1<<" "<<*it2<<endl;
                else
                {
                    if(a[*it1][*it2] == 1)
                        cout<<*it1<<" "<<*it2<<endl;
                }
            }
        cout<<endl;
    }
    return 0;
}




/***************************************************
Result: Wrong Answer
Take time: 96ms
****************************************************/



后来经过尝试知道,在本题中只是并上 在“叙述关系时出现的元素的自反序偶”,比如此题在叙述关系时没有提到4,那么就不能并上<4,4>;

以下为AC代码

#include <bits/stdc++.h>

using namespace std;

set<int> s;
int a[101][101];
int main()
{
    int m, n, k;
    cin>>k;
    while(k--)
    {
        int x,y;
        cin>>m;
        s.clear();
        for(int i = 0; i < m; i++)
        {
            cin>>x;
            s.insert(x);
        }

        memset(a,0,sizeof(a));

        cin>>n;

        for(int i = 0; i < n; i++)
        {
            cin>>x>>y;
            a[x][y] = 1;//在此处标记出现过的元素,下面只输出出现过元素的自反序偶;
            a[x][x] = 1;
            a[y][y] = 1;
        }

        set<int>::iterator it1, it2;

        for(it1 = s.begin(); it1 != s.end(); it1++)
            for(it2 = s.begin(); it2 != s.end(); it2++)
            {
                if(a[*it1][*it2] == 1)//只输出键值为1,即标记过的出现过的序偶,及其自反序偶;
                    cout<<*it1<<" "<<*it2<<endl;
            }
        cout<<endl;
    }
    return 0;
}




/***************************************************
User name:
Result: Accepted
Take time: 32ms

****************************************************/


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值