算法题(牛的学术圈)

119 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情

牛的学术圈

题目描述

Bessie 正在申请计算机科学的研究生,并取得了一所久负盛名的计算机科学实验室的面试通知。

然而,为了避免冒犯任何人,Bessie 有意先确定实验室的 NN 名现有成员的相对资历。

没有两名实验室成员的资历相同,但确定他们的资历深浅可能并不好办。

为此,Bessie 将会对实验室的出版物进行调查。

每份出版物均包含一个作者列表,为所有 NN 名实验室成员的一个排列。

列表按每名实验室成员对这篇文章的贡献降序排列。

如果多名研究员的贡献相等,则按字典序排列。

由于更有资历的实验室成员负有更多的管理责任,更有资历的研究员从不会比资历较浅的研究员做出更多的贡献。

例如,在一个由资历较浅的学生 Elsie、资历较深的教授 Mildred、以及十分资深的教授 Dean 组成的实验室中,可能存在一篇论文 Elsie-Mildred-Dean,如果他们做出了不等的贡献(也就是说,Elsie 做出的贡献比 Mildred 更多,Mildred 比 Dean 更多)。

然而,也有可能存在一篇论文 Elsie-Dean-Mildred,如果 Mildred 和 Dean 做出了相等的贡献,而 Elsie 做出了更多的贡献。

给定实验室的 KK 份出版物,对于实验室中每对研究员,如果可能的话帮助 Bessie 判断其中谁的资历更深。

输入格式

输入的第一行包含两个整数 KK 和 NN。

第二行包含 NN 个空格分隔的字符串,为实验室的成员的名字。每个字符串均由小写字母组成,且至多包含 1010 个字符。

以下 KK 行,每行包含 NN 个空格分隔的字符串,表示一份出版物的作者列表。

输出格式

输出 NN 行,每行 NN 个字符。在第 ii 行内,对于所有 j≠ij≠i,当可以确定第 ii 名成员比第 jj 名成员资历更深时字符 jj 为 1,当可以确定第 ii 名成员比第 jj 名成员资历更浅时字符 jj 为 0,当不能由给定的出版物确定时为 ?

第 ii 行的字符 ii 应为 B,因为这是 Bessie 最喜欢的字母。

数据范围

1≤N,K≤1001≤N,K≤100

输入样例1:

1 3
dean elsie mildred
elsie mildred dean

输出样例1:

B11
0B?
0?B

样例1解释

在这个样例中,单独一份论文 elsie-mildred-dean 并不能提供足够的信息判断 Elsie 比 Mildred 资历更深或更浅。

然而,我们可以推断出 Dean 一定比这两名研究员资历更深,从而资历排序为 Elsie<Mildred<Dean 和 Mildred<Elsie<Dean 均是可能的。

输入样例2:

2 3
elsie mildred dean
elsie mildred dean
elsie dean mildred

输出样例2:

B00
1B0
11B

样例2解释

在这个样例中,唯一能与两篇论文相一致的资历排序为 Elsie<Mildred<Dean,这是因为基于第一个样例所提供的信息,第二篇论文可以帮助我们推断出 Mildred 比 Elsie 的资历更深。

代码:

#include <bits/stdc++.h>
using namespace std;
int n, k, a[110][110];
map<string, int> name;
string s, x[110];
int main() {
    cin >> k >> n;
    for (int i = 1;i <= n; i++) for (int j = 1;j <= n; j++) a[i][j] = 2;
    for (int i = 1;i <= n; i++) cin >> s, name[s] = i;
    int A = 0;
    while (k--) {
        A = 1;
        for (int i = 1;i <= n; i++) {
            cin >> x[i];
            if (x[i] < x[i - 1]) A = i;
            for (int j = 1;j < A; j++)
                a[name[x[i]]][name[x[j]]] = 1, a[name[x[j]]][name[x[i]]] = 0;
        }
    }
    for (int i = 1;i <= n; i++) {
        for (int j = 1;j <= n; j++) {
            if (i == j) {printf("B"); continue;}
            if (a[i][j] != 2) printf("%d", a[i][j]);
            else printf("?");
        }
        puts("");
    }
    return 0;
}