1139 First Contact PAT (Advanced Level)
原题链接:
https://pintia.cn/problem-sets/994805342720868352/problems/994805344776077312
1139 First Contact (30 分)
Unlike in nowadays, the way that boys and girls expressing their feelings of love was quite subtle in the early years. When a boy A had a crush on a girl B, he would usually not contact her directly in the first place. Instead, he might ask another boy C, one of his close friends, to ask another girl D, who was a friend of both B and C, to send a message to B -- quite a long shot, isn't it? Girls would do analogously.
Here given a network of friendship relations, you are supposed to help a boy or a girl to list all their friends who can possibly help them making the first contact.
Input Specification:
Each input file contains one test case. For each case, the first line gives two positive integers N (1 < N ≤ 300) and M, being the total number of people and the number of friendship relations, respectively. Then M lines follow, each gives a pair of friends. Here a person is represented by a 4-digit ID. To tell their genders, we use a negative sign to represent girls.
After the relations, a positive integer K (≤ 100) is given, which is the number of queries. Then K lines of queries follow, each gives a pair of lovers, separated by a space. It is assumed that the first one is having a crush on the second one.
Output Specification:
For each query, first print in a line the number of different pairs of friends they can find to help them, then in each line print the IDs of a pair of friends.
If the lovers A and B are of opposite genders, you must first print the friend of A who is of the same gender of A, then the friend of B, who is of the same gender of B. If they are of the same gender, then both friends must be in the same gender as theirs. It is guaranteed that each person has only one gender.
The friends must be printed in non-decreasing order of the first IDs, and for the same first ones, in increasing order of the seconds ones.
Sample Input:
10 18
-2001 1001
-2002 -2001
1004 1001
-2004 -2001
-2003 1005
1005 -2001
1001 -2003
1002 1001
1002 -2004
-2004 1001
1003 -2002
-2003 1003
1004 -2002
-2001 -2003
1001 1003
1003 -2001
1002 -2001
-2002 -2003
5
1001 -2001
-2003 1001
1005 -2001
-2002 -2004
1111 -2003
结尾无空行
Sample Output:
4
1002 2004
1003 2002
1003 2003
1004 2002
4
2001 1002
2001 1003
2002 1003
2002 1004
0
1
2003 2001
0
结尾无空行
测试点分析:
首先来分析一下测试点,这样可以站在命题者的角度来分析问题。
测试点 | 分值 | 数据特点 |
0 | 18 | 主测试点,10<=n<70,没有***难性的数据,数据量一般,ID从0001到3000即可通过,测试基本功能。 |
1 | 4 | n=7,存在+0000数据,但不存在-0000数据,ID从0000到5000。 |
2 | 2 | n=7,存在-0000数据,但不存在+0000数据,ID从0000到5000。 |
3 | 1 | n=2,涉及同性恋问题,ID范围非常大,几乎是0001到9999。 |
4 | 1 | n=3,涉及同性恋问题,ID范围非常大,几乎是0001到9999。 |
5 | 4 | 70<=n<=300,ID范围非常大,几乎是0001到9999,不存在特殊数据,但是数据量大,要求程序相当完美。 |
***难性数据分析:
测试点1和2形成对比,虽然n=7不大,ID范围也不大,但是存在0000的数据,意味着如果输出时没有调整成%04d的格式则无法通过。
如果默认所有的0都是+0000,则测试点2不能通过,这就要求程序考虑到+0000和-0000的区别,虽然对整数来说是一样的。
如果+0000和-0000没有区分出来,则测试点1和测试点2至少有1个不能通过,又n均为7,其余数据估计几乎相同(除了+和-),所以很难不判断+-就都通过。
测试点3和测试点4类似,均涉及同性恋问题,虽然n非常小,但是如果没有考虑同性恋,这2个测试点均无法通过。
同性恋问题主要不是要考虑性别因素,而是需要考虑人是否重复。
假设A暗恋B,A认识C认识D认识B。如果是异性恋,不妨设A为男,则AC男,BD女,因为题目给出一个人不会拥有2个性别,所以A!=D,B!=C,不会出现问题。
如果是同性恋,不妨设A为男,则ACDB均为男,但是如果程序不加考虑,则可能出现A==D或B==C的情况,所以导致Wrong Answer。
测试点5主要是数据规模均设置为最大,看程序能不能承受大量数据的测试,如果代码过于暴力,则可能无法通过该测试点。
代码分析:
利用先读一个字符的方法判断性别,g数组存放两人是否认识,下标直接是ID。
gen数组存放每人的性别,1表示男,2表示女,0表示未定义,下标直接是ID。hash数组用于存放所有的ID。
通过性别是否定义过判断某个ID是否首次出现,首次出现就将ID压入hash数组里。
最后等所有ID都进去了,再调一次快速排序把hash数组里的数据排序一下,主要是要保证输出的顺序。
AC代码:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #define N 10000 4 5 int g[N][N],gen[N],tmp[5*N][2],hash[302],haN; 6 7 int inc(const void *a,const void *b) 8 { 9 return *(int *)a-*(int *)b; 10 } 11 12 int ab(int num) 13 { 14 if(num<0) 15 num=-num; 16 return num; 17 } 18 19 int main(void) 20 { 21 int n=0,m=0,k=0,g1=0,g2=0,g3=0,g4=0; 22 char c1='\0',c2='\0'; 23 scanf("%d%d",&n,&m); 24 while(m--) 25 { 26 scanf("%*c%c%d%*c%c%d",&c1,&g1,&c2,&g2); 27 //+0000 or -0000 AC!!! 28 if(c1!='-') 29 g1=(c1-'0')*1000+g1; 30 if(gen[g1]==0) 31 hash[haN++]=g1; 32 gen[g1]=c1!='-'?1:2; 33 if(c2!='-') 34 g2=(c2-'0')*1000+g2; 35 if(gen[g2]==0) 36 hash[haN++]=g2; 37 gen[g2]=c2!='-'?1:2; 38 g[ab(g1)][ab(g2)]=g[ab(g2)][ab(g1)]=1; 39 } 40 qsort(hash,haN,4,inc); 41 scanf("%d",&k); 42 while(k--) 43 { 44 int tmpN=0; 45 scanf("%d%d",&g1,&g2); 46 g1=ab(g1),g2=ab(g2); 47 for(g3=0;g3<haN;g3++) 48 { 49 if(gen[g1]^gen[hash[g3]]||!g[g1][hash[g3]]||hash[g3]==g2)//must not the same 50 continue; 51 for(g4=0;g4<haN;g4++) 52 if(gen[hash[g4]]==gen[g2]&&g[hash[g4]][g2]&&g[hash[g3]][hash[g4]]&&g1^hash[g4])//must not the same 53 tmp[tmpN][0]=hash[g3],tmp[tmpN][1]=hash[g4],++tmpN; 54 } 55 printf("%d\n",tmpN); 56 for(m=0;m<tmpN;m++) 57 printf("%04d %04d\n",tmp[m][0],tmp[m][1]); 58 } 59 return 0; 60 }
posted on 2019-08-30 16:20 Leisureeen 阅读(489) 评论(0) 编辑 收藏 举报