原题链接:
https://pintia.cn/problem-sets/994805342720868352/problems/994805344776077312
测试点分析:
首先来分析一下测试点,这样可以站在命题者的角度来分析问题。
测试点 | 分值 | 数据特点 |
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 }