QDU天梯选拔赛

  经过PTA甲和天梯选拔我对自己产生了严重的怀疑,我不知道我现在坚持的是不是对的。我不能说我自己是最努力的那个,但肯定是最努力的那些人中的一个,我不知道为什么差距会那么大。也不知道怎么才能从自我否定、自我怀疑里把自己拉出来。

   我只能说,可能是我学的还不够,学习方法不正确,可能我想得太多,可能我太敏感。我以为我把自己从什么社团组织里拖出来就能静下心来,我以为我把追求者们的路一下子截断就可以让自己不进感情的坑,我以为我把我自己完全投入到学习里就可以学得很好。我总是在做每件事的时候都有一份期待在里面,这份期待往往会让我失望透顶。

    再试一次吧,还有蓝桥呢,我不信我不行,我也不信,他们天生就比我强,我不信。

L1-1 天梯赛座位分配 (20 分)

天梯赛每年有大量参赛队员,要保证同一所学校的所有队员都不能相邻,分配座位就成为一件比较麻烦的事情。为此我们制定如下策略:假设某赛场有 N 所学校参赛,第 i 所学校有 M[i] 支队伍,每队 10 位参赛选手。令每校选手排成一列纵队,第 i+1 队的选手排在第 i 队选手之后。从第 1 所学校开始,各校的第 1 位队员顺次入座,然后是各校的第 2 位队员…… 以此类推。如果最后只剩下 1 所学校的队伍还没有分配座位,则需要安排他们的队员隔位就坐。本题就要求你编写程序,自动为各校生成队员的座位号,从 1 开始编号。

输入格式:

输入在一行中给出参赛的高校数 N (不超过100的正整数);第二行给出 N 个不超过10的正整数,其中第 i 个数对应第 i 所高校的参赛队伍数,数字间以空格分隔。

输出格式:

从第 1 所高校的第 1 支队伍开始,顺次输出队员的座位号。每队占一行,座位号间以 1 个空格分隔,行首尾不得有多余空格。另外,每所高校的第一行按“#X”输出该校的编号X,从 1 开始。

输入样例:

3
3 4 2

输出样例:

#1
1 4 7 10 13 16 19 22 25 28
31 34 37 40 43 46 49 52 55 58
61 63 65 67 69 71 73 75 77 79
#2
2 5 8 11 14 17 20 23 26 29
32 35 38 41 44 47 50 53 56 59
62 64 66 68 70 72 74 76 78 80
82 84 86 88 90 92 94 96 98 100
#3
3 6 9 12 15 18 21 24 27 30
33 36 39 42 45 48 51 54 57 60
#include
#include
#include
using namespace std;
#define maxn 105
int res[105][105][105];
int n;
int team[maxn];
int maxx = 0;
int main()
{
    scanf("%d",&n);
    for(int i = 0; i < n; i ++)
    {
        scanf("%d",&team[i]);
        maxx = max(maxx,team[i]);//找出数量最大的队伍。
    }
    int lastshool = -1;
    int position = 0;
    for(int j = 0; j < maxx; j ++)
    {
        for(int k = 0; k < 10; k ++)
        {
            for(int i = 0; i < n; i ++)
            {
                if(j

L1-2 Excel列名和列序号转换 (15 分)

大家有没有留意过Excel表格中列名的规律呢?是这样的:
A B C ... Y Z AA AB AC ... AY AZ BA BB BC ... BY BZ ... ZZ ... AAA ...
如果没看懂,请打开Excel程序仔细观察一下~~
每一列都是有序号的,从1开始编号,即:列A B C ... Y Z AA AB ... 的编号依次是 1 2 3 ... 25 26 27 28 ...
现在,请编写程序,按照上述规律,把输入的列名和列序号进行相互转换(不用考虑Excel软件实际允许的最多列数)。

输入格式:

输入由若干行组成,每行的内容是以下三种之一:

  • 长度不超过6的由大写字母组成的字符串,表示一个列名
  • 不超过9位数字的正整数,表示一个列序号
  • 符号#,表示输入结束

输出格式:

对于在输入结束符#之前出现的每一行输入,若输入为列名,在一行内打印对应的列序号;若输入为列序号,在一行内打印对应的列名。

输入样例:

A
3
AB
29
#

输出样例:

1
C
28
AC

 

#include
#include
#include
using namespace std;
char indexs[105];
int main()
{
	string a;
	int flag  = 0;
	while(cin>>a)
	{
		if(a=="#")
			break;
		flag = 0;
		int cnt = 0;
		int len = a.length();
		long long int num = 0;
		for(int i = 0; i < len; i ++)
		{
			if(a[i]>='0'&&a[i]<='9')
				num = num*10 + a[i] - '0';
			else
			{
				num = num*26 + a[i]-'A' + 1;
				flag = 1;
			}
		}
		if(flag)
			printf("%d\n",num);
		else
		{
			while(num)
			{
				if(num%26==0)
				{
					indexs[cnt] = 26+64;
					cnt++;
					num = num/26;
					num--;
				}
				else
				{
					indexs[cnt] = num%26 + 64;
					cnt++;
					num /= 26;
				}
 
			}
		for(int i = cnt - 1; i >= 0; i --)
			printf("%c",indexs[i]);
		printf("\n");
 
		}
 
 
	}
}

 

L1-3 算术入门之加减乘除 (5 分)

对于输入的两个整数,按照要求输出其和差积商。

输入格式:

在一行内输入两个不超过100的非负整数a和b,中间以一个空格间隔,且保证b不为0。

输出格式:

共四行,格式是:

[a] + [b] = [a+b]
[a] - [b] = [a-b]
[a] * [b] = [a*b]
[a] / [b] = [a/b]

其中,带有方括号的内容(如[a][b][a+b]等)表示相应整数或运算结果的值,在输出时要用实际的值代替。

并且:如果a能够被b整除,那么a/b应输出为整数格式,否则a/b输出为带两位小数的格式。

提示:注意表达式中的空格。

输入样例1:

6 3

输出样例1:

6 + 3 = 9
6 - 3 = 3
6 * 3 = 18
6 / 3 = 2

输入样例2:

8 6

输出样例2:

8 + 6 = 14
8 - 6 = 2
8 * 6 = 48
8 / 6 = 1.33
#include
#include
#include
using namespace std;
#define maxn 105
int main()
{
    int a,b;
    scanf("%d %d",&a,&b);
    printf("%d + %d = %d\n",a,b,a+b);
    printf("%d - %d = %d\n",a,b,a-b);
    printf("%d * %d = %d\n",a,b,a*b);
    if(a%b)
    {
        double c = 1.0*a/b;
        printf("%d / %d = %.2f\n",a,b,c);
    }
    else
        printf("%d / %d = %d\n",a,b,a/b);
}

 

L1-4 Say Hello to Integers (5 分)

Say hello to integers? Yes! 你没看错! 现在我们来向整数说“你好~” 本题读入两个整数,然后输出对她们的问候语。
输入格式:

在一行中给出两个绝对值不超过32767的整数A和B,两数之间有一个空格
输出格式:

在一行中输出 "Hello, A and B!" (其中A和B用实际输入的整数代替)
输入样例:

1949 2015

输出样例:

Hello, 1949 and 2015!

#include
#include
#include
using namespace std;
#define maxn 105
int main()
{
    int a,b;
    scanf("%d %d",&a,&b);
    printf("Hello, %d and %d!",a,b);
}

L1-5 刷题与Z老师的头发 (10 分)

在Pintia上,每天Z老师出题、小盆友们刷题。Z老师的头发遵从以下规律:
1、每天生长出60根头发;
2、每出一道题,减少20根头发;
3、每天结束时统计累积做题情况:
(1)若出的题全部被做出来,则Z老师产生“没题焦虑”,减少30根头发;
(2)若小盆友做出来的题少于50%,则Z老师产生“学生不用功焦虑”,减少70根头发。
现给定连续N天的出题、刷题情况,请计算Z老师头发的变化情况。

输入格式:

第一行输入一个正整数N (N<20);
接下来N行,每行输入两个非负整数,分别是一天的出题数量q和刷题(做出来)数量s,以空格间隔。
题目输入保证出题总数量不超过N*10,并且每天的刷题量不会使累积刷题数量超过累积出题数量。

输出格式:

若Z老师头发增加K根,则输出+K;若Z老师头发减少K根,则输出-K;若没有变化,则输出--

输入样例1:

3
5 3
5 1
5 11

输出样例1:

-220

输入样例2:

3
3 2
3 2
3 2

输出样例2:

--

这个题最后也没AC, 看了舍友的代码才知道要出题量和刷题量都要累加。

#include
using namespace std;

int main(void){
	int n;
	int sumc = 0, sumz = 0;
	int a, b;
	int k = 0;
	scanf("%d", &n);
	for(int i = 0; i < n; i++){
		k = k + 60;
		scanf("%d %d", &a, &b);
		k = k - a * 20;
		sumc += a;
		sumz += b;
		if(0.5 * sumc > 1.0 * sumz) k = k - 70;
		if(sumc == sumz) k = k - 30;
	} 
	if(k > 0){
		printf("+%d\n", k);
	}
	else if (k < 0){
		printf("%d\n", k);
	}
	else{
		printf("--\n");
	}
	return 0;
}

L1-6 福到了 (15 分)

“福”字倒着贴,寓意“福到”。不论到底算不算民俗,本题且请你编写程序,把各种汉字倒过来输出。这里要处理的每个汉字是由一个 N × N 的网格组成的,网格中的元素或者为字符 @ 或者为空格。而倒过来的汉字所用的字符由裁判指定。

输入格式:

输入在第一行中给出倒过来的汉字所用的字符、以及网格的规模 N (不超过100的正整数),其间以 1 个空格分隔;随后 N 行,每行给出 N 个字符,或者为 @ 或者为空格。

输出格式:

输出倒置的网格,如样例所示。但是,如果这个字正过来倒过去是一样的,就先输出bu yong dao le,然后再用输入指定的字符将其输出。

输入样例 1:

$ 9
 @  @@@@@
@@@  @@@ 
 @   @ @ 
@@@  @@@ 
@@@ @@@@@
@@@ @ @ @
@@@ @@@@@
 @  @ @ @
 @  @@@@@

输出样例 1:

$$$$$  $ 
$ $ $  $ 
$$$$$ $$$
$ $ $ $$$
$$$$$ $$$
 $$$  $$$
 $ $   $ 
 $$$  $$$
$$$$$  $ 

输入样例 2:

& 3
@@@
 @ 
@@@

输出样例 2:

bu yong dao le
&&&
 & 
&&&

读入一直在WA,后来用getchar(),就神奇地可以了,学到了。

读入以后逆着进一个新数组就行了。

#include
#include
#include
using namespace std;
#define maxn 2005
int n;
char ch;
char mapp[105][105];
char newmap[105][105];
int main()
{
    scanf("%c",&ch);
    scanf("%d",&n);
   getchar();
    for(int i = 0; i < n; i ++)
    {
        for(int j = 0; j < n; j ++)
        {
            mapp[i][j] = getchar();
        }
        getchar();
    }
    for(int i = 0; i < n; i ++)
        for(int j = 0; j < n; j ++)
            newmap[i][j] = ' ';
    for(int i = 0; i < n; i ++)
    {
        for(int j = 0; j < n; j ++)
        {
            if(mapp[n-i-1][n-j-1]==' ')
                newmap[i][j] = ' ';
            else
                newmap[i][j] = ch;
        }
    }
    int flag = 0;
    for(int i = 0; i < n; i ++)
    {
        for(int j = 0; j < n; j ++)
          {
                if(mapp[i][j]==' '&&newmap[i][j]==' ')
                continue;
                else if(mapp[i][j]!=' '&&newmap[i][j]!=' ')
                    continue;
                else
                {
                    flag = 1;
                    break;
                }
          }
          if(flag)
            break;
    }
    if(!flag)
        printf("bu yong dao le\n");
    for(int i = 0; i < n; i ++)
      {
            for(int j = 0; j < n; j ++)
            {
            printf("%c",newmap[i][j]);
            }
            printf("\n");
      }
}

L1-7 谁是赢家 (10 分)

某电视台的娱乐节目有个表演评审环节,每次安排两位艺人表演,他们的胜负由观众投票和 3 名评委投票两部分共同决定。规则为:如果一位艺人的观众票数高,且得到至少 1 名评委的认可,该艺人就胜出;或艺人的观众票数低,但得到全部评委的认可,也可以胜出。节目保证投票的观众人数为奇数,所以不存在平票的情况。本题就请你用程序判断谁是赢家。

输入格式:

输入第一行给出 2 个不超过 1000 的正整数 Pa 和 Pb,分别是艺人 a 和艺人 b 得到的观众票数。题目保证这两个数字不相等。随后第二行给出 3 名评委的投票结果。数字 0 代表投票给 a,数字 1 代表投票给 b,其间以一个空格分隔。

输出格式:

按以下格式输出赢家:

The winner is x: P1 + P2

其中 x 是代表赢家的字母,P1 是赢家得到的观众票数,P2 是赢家得到的评委票数。

输入样例:

327 129
1 0 1

输出样例:

The winner is a: 327 + 1
#include
#include
#include
using namespace std;
#define maxn 2005
int a,b;
int aa,bb;
int main()
{
    scanf("%d %d",&a,&b);
    for(int i = 0; i < 3; i ++)
    {
        int x;
        scanf("%d",&x);
        if(x)
            bb++;
        else
            aa++;
    }
    if(aa&&a>b||aa==3)
        printf("The winner is a: %d + %d",a,aa);
    else if(bb&&a

 

L1-8 猜数字 (20 分)

一群人坐在一起,每人猜一个 100 以内的数,谁的数字最接近大家平均数的一半就赢。本题就要求你找出其中的赢家。

输入格式:

输入在第一行给出一个正整数N(≤10​4​​)。随后 N 行,每行给出一个玩家的名字(由不超过8个英文字母组成的字符串)和其猜的正整数(≤ 100)。

输出格式:

在一行中顺序输出:大家平均数的一半(只输出整数部分)、赢家的名字,其间以空格分隔。题目保证赢家是唯一的。

输入样例:

7
Bob 35
Amy 28
James 98
Alice 11
Jack 45
Smith 33
Chris 62

输出样例:

22 Amy

结构体的应用,再排个序。

#include
#include
#include
using namespace std;
#define maxn 100005
struct node{
    string name;
    int num;
}s[maxn];
int main()
{
    int n;
    scanf("%d",&n);
    int sum = 0;
    for(int i = 0; i < n; i ++)
    {
        cin>>s[i].name;
        scanf("%d",&s[i].num);
        sum += s[i].num;
    }
    int ave = sum/n;
    ave = ave/2;
    int minn = maxn;
    int index = 0;
    for(int i = 0; i < n; i ++)
    {
         int temp = s[i].num - ave;
         if(temp < 0)
            temp = -temp;
         if(temp

L2-1 分而治之 (25 分)

分而治之,各个击破是兵家常用的策略之一。在战争中,我们希望首先攻下敌方的部分城市,使其剩余的城市变成孤立无援,然后再分头各个击破。为此参谋部提供了若干打击方案。本题就请你编写程序,判断每个方案的可行性。

输入格式:

输入在第一行给出两个正整数 N 和 M(均不超过10 000),分别为敌方城市个数(于是默认城市从 1 到 N 编号)和连接两城市的通路条数。随后 M 行,每行给出一条通路所连接的两个城市的编号,其间以一个空格分隔。在城市信息之后给出参谋部的系列方案,即一个正整数 K (≤ 100)和随后的 K 行方案,每行按以下格式给出:

Np v[1] v[2] ... v[Np]

其中 Np 是该方案中计划攻下的城市数量,后面的系列 v[i] 是计划攻下的城市编号。

输出格式:

对每一套方案,如果可行就输出YES,否则输出NO

输入样例:

10 11
8 7
6 8
4 5
8 4
8 1
1 2
1 4
9 8
9 1
1 10
2 4
5
4 10 3 8 4
6 6 1 7 5 4 9
3 1 8 4
2 2 8
7 9 8 7 6 5 4 2

输出样例:

NO
YES
YES
NO
NO

 

#include
#include
#include
#include
using namespace std;
#define maxn 100005
struct node{
    int x,y;
}s[maxn];
int main()
{
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i = 0; i < m; i ++)
    {
        scanf("%d %d",&s[i].x,&s[i].y);
    }
    int k;
    scanf("%d",&k);
    while(k--)
    {
        int flag = 0;
        mapq;
        int t;
        scanf("%d",&t);
        for(int i = 0; i < t; i ++)
        {
            int x;
            scanf("%d",&x);
            q[x] = 1;
        }
        for(int i = 0; i < m; i ++)
        {
            if(q[s[i].x]!=1&&q[s[i].y]!=1)
            {
                printf("NO\n");
                flag = 1;
                break;
            }
        }
        if(!flag)
          printf("YES\n");
    }
}

L2-2 小字辈(左子右兄加强版) (25 分)

本题给定一个庞大家族的家谱,要请你给出最小一辈的名单。
需要注意的是,家族成员的输入方式,是按照“Left-child Right-sibling”(左儿子 右兄弟)的格式
【敲黑板】sibling的意思是兄弟/姐妹,是亲兄弟,不是“表兄弟”!2019年春季PAT中不认识单词sibling的孩纸请牢记……
注:本题是在浙江大学陈越老师的GPLT-2018决赛L2-2题目“小字辈”题意基础上改编而成。

输入格式:

输入在第一行给出家族人口总数 N(不超过 100 000 的正整数) —— 简单起见,我们把家族成员从 1 到 N 编号。
随后的N行,每行给出1名家族成员的编号以及他的亲属关系,格式为3个以空格间隔的整数A B C
其中的A(范围1~N)是1名家族成员编号(每行的编号必定各不相同)
B的范围是0~N,当B不为0,表示A有儿子B
C的范围是0~N,当C不为0,表示A有兄弟C
题目保证输入是正确的,即:只有一个家族(没有分离成家族群),且家族中只有一位老祖宗(老祖宗即:他不是任何其他人的儿子)

输出格式:

首先输出最小的辈分(老祖宗的辈分最大、数值为 1,子孙的辈分数值逐级递增1)。
然后在第二行按递增顺序输出辈分最小的成员的编号。编号间以一个空格分隔,行首尾不得有多余空格。

输入样例1:

5
1 2 0
2 4 3
3 0 0
4 0 5
5 0 0

输出样例1:

3
4 5

输入样例2:

5
2 5 3
1 2 0
3 0 0
4 0 0
5 0 4

输出样例2:

3
4 5

 

#include 
#define maxn 100005
#define INF 0x3f3f3f3f
using namespace std;
struct Node{
    int Left;
    int Right;
    int flag;
}a[maxn];

int b[maxn];
int vis[maxn] = {0};

int M = 0;

void BFS(int root){
    queue q;
    q.push(a[root]);
    while(!q.empty()){
        Node t = q.front();
        if(t.flag > M)
            M = t.flag;
        q.pop();
        if(t.Left > 0 && vis[t.Left] == 0){
            vis[t.Left] = 1;
            a[t.Left].flag = t.flag + 1;
            q.push(a[t.Left]);
        }
        if(t.Right > 0 && vis[t.Right] == 0){
            vis[t.Right] = 1;
            a[t.Right].flag = t.flag;
            q.push(a[t.Right]);
        }
    }
}


int main(){
    int n;
    scanf("%d",&n);
    int t;
    for(int i = 0;i < maxn;i++){
        a[i].Left = a[i].Right = 0;
        b[i] = 0;
    }
    for(int i = 0;i < n;i++){
        scanf("%d",&t);
        scanf("%d %d",&a[t].Left,&a[t].Right);
        b[a[t].Left] = 1;
        b[a[t].Right] = 1;
    }
    int Root;
    for(int i = 1;i <= n;i++){
        if(b[i] == 0){
            Root = i;
            break;
        }
    }
    a[Root].flag = 1;
    vis[Root] = 1;
    BFS(Root);
    int temp = 0;
    printf("%d\n",M);
    for(int i = 1;i <= n;i++){
        if(a[i].flag == M){
            if(temp == 0){
                printf("%d",i);
                temp = 1;
            }
            else
                printf(" %d",i);
        }
    }
    return 0;
}

L2-3 名人堂与代金券 (25 分)

对于在中国大学MOOC(http://www.icourse163.org/ )学习“数据结构”课程的学生,想要获得一张合格证书,总评成绩必须达到 60 分及以上,并且有另加福利:总评分在 [G, 100] 区间内者,可以得到 50 元 PAT 代金券;在 [60, G) 区间内者,可以得到 20 元PAT代金券。全国考点通用,一年有效。同时任课老师还会把总评成绩前 K 名的学生列入课程“名人堂”。本题就请你编写程序,帮助老师列出名人堂的学生,并统计一共发出了面值多少元的 PAT 代金券。

输入格式:

输入在第一行给出 3 个整数,分别是 N(不超过 10 000 的正整数,为学生总数)、G(在 (60,100) 区间内的整数,为题面中描述的代金券等级分界线)、K(不超过 100 且不超过 N 的正整数,为进入名人堂的最低名次)。接下来 N 行,每行给出一位学生的账号(长度不超过15位、不带空格的字符串)和总评成绩(区间 [0, 100] 内的整数),其间以空格分隔。题目保证没有重复的账号。

输出格式:

首先在一行中输出发出的 PAT 代金券的总面值。然后按总评成绩非升序输出进入名人堂的学生的名次、账号和成绩,其间以 1 个空格分隔。需要注意的是:成绩相同的学生享有并列的排名,排名并列时,按账号的字母序升序输出。

输入样例:

10 80 5
[email protected] 78
[email protected] 87
[email protected] 65
[email protected] 96
[email protected] 39
[email protected] 87
[email protected] 80
[email protected] 88
[email protected] 80
[email protected] 70

输出样例:

360
1 [email protected] 96
2 [email protected] 88
3 [email protected] 87
3 [email protected] 87
5 [email protected] 80
5 [email protected] 80

结构体排序。

#include
#include
#include
#include
using namespace std;
#define maxn 100005
struct node{
    string name;
    int grade;
    int rank;
}s[maxn];
int cmp(struct node a,struct node b)
{
    if(a.grade == b.grade)
        return a.name b.grade;
}
int main()
{
    int n,g,k;
    int fify = 0,twenty = 0;
    scanf("%d %d %d",&n,&g,&k);
    for(int i = 0; i < n; i ++)
    {
        cin>>s[i].name;
        scanf("%d",&s[i].grade);
        if(s[i].grade >= g)
            fify++;
        else if(s[i].grade>=60&&s[i].gradek)
            break;
         cout<

L2-4 秀恩爱分得快 (25 分)

古人云:秀恩爱,分得快。

互联网上每天都有大量人发布大量照片,我们通过分析这些照片,可以分析人与人之间的亲密度。如果一张照片上出现了 K 个人,这些人两两间的亲密度就被定义为 1/K。任意两个人如果同时出现在若干张照片里,他们之间的亲密度就是所有这些同框照片对应的亲密度之和。下面给定一批照片,请你分析一对给定的情侣,看看他们分别有没有亲密度更高的异性朋友?

输入格式:

输入在第一行给出 2 个正整数:N(不超过1000,为总人数——简单起见,我们把所有人从 0 到 N-1 编号。为了区分性别,我们用编号前的负号表示女性)和 M(不超过1000,为照片总数)。随后 M 行,每行给出一张照片的信息,格式如下:

K P[1] ... P[K]

其中 K(≤ 500)是该照片中出现的人数,P[1] ~ P[K] 就是这些人的编号。最后一行给出一对异性情侣的编号 A 和 B。同行数字以空格分隔。题目保证每个人只有一个性别,并且不会在同一张照片里出现多次。

输出格式:

首先输出 A PA,其中 PA 是与 A 最亲密的异性。如果 PA 不唯一,则按他们编号的绝对值递增输出;然后类似地输出 B PB。但如果 AB 正是彼此亲密度最高的一对,则只输出他们的编号,无论是否还有其他人并列。

输入样例 1:

10 4
4 -1 2 -3 4
4 2 -3 -5 -6
3 2 4 -5
3 -6 0 2
-3 2

输出样例 1:

-3 2
2 -5
2 -6

输入样例 2:

4 4
4 -1 2 -3 0
2 0 -3
2 2 -3
2 -1 2 
-3 2

输出样例 2:

-3 2
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn =  1e5 + 5;
#define inf 0x3f3f3f
bool gender[100005];
int read()
{
    int flag = 0;
    char a = getchar();
    while((a<'0'||a>'9')&&a!='-')
        a = getchar();
    if(a=='-')
    {
        flag = 1;
        a = getchar();
    }
    int num = 0;
    while(a>='0'&&a<='9')
     {
        num = num*10 + a - '0';
        a = getchar();
     }
     gender[num] = flag;
     return num;

}
int main()
{
    int n,m;
    scanf("%d %d",&n,&m);
    double pa_max = 0.0,pb_max = 0.0;
    vector>p(n);
    vectorpa(n,0.0),pb(n,0.0);
    for(int i = 0; i < m; i ++)
    {
        int k;
        scanf("%d",&k);
        p[i].resize(k);
        for(int j = 0; j < k; j ++)
            p[i][j]= read();
    }
    int a,b;
    a = read(),b = read();
    for(int i = 0; i < m; i ++)
    {
        int founda = (find(p[i].begin(),p[i].end(),a) != p[i].end());
        int foundb = (find(p[i].begin(),p[i].end(),b) != p[i].end());
        if(founda||foundb)
        {
            for(int j = 0; j < p[i].size(); j ++)
            {
                if(founda&&gender[a]!=gender[p[i][j]])
                {
                    pa[p[i][j]] += 1.0/p[i].size();
                    pa_max = max(pa_max,pa[p[i][j]]);
                }
                else if(foundb&&gender[b]!=gender[p[i][j]])
                {
                    pb[p[i][j]] += 1.0/p[i].size();
                    pb_max = max(pb_max,pb[p[i][j]]);
                }
            }
        }
    }
    if(pa_max==pa[b]&&pb_max==pb[a])
        printf("%s%d %s%d\n",gender[a]?"-":"",a,gender[b]?"-":"",b);
    else
    {
        for(int i =0; i < n; i ++)
        {
            if(pa[i]==pa_max)
                printf("%s%d %s%d\n",gender[a]?"-":"",a,gender[i]?"-":"",i);
        }
        for(int i =0; i < n; i ++)
        {
            if(pb[i]==pb_max)
                printf("%s%d %s%d\n",gender[b]?"-":"",b,gender[i]?"-":"",i);
        }
    }
}

 

你可能感兴趣的:(天梯)