PAT 1063 Set Similarity (25)
题意:给你n个集合,k次询问,每次询问求两个集合的(交集)/(并集)。
思路:k有2000,集合大小有10000。先将每个集合排序,对每个询问分别设两个指针指向两个集合的头。设a[i]为指针1的值,b[j]为指针2的值。如果a[i]==b[j],交集加一;如果不相同,值较小的指针向后移一位;每次都要去重,并且并集加一。
代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 const int N=1e4+11; 6 int a[51][N],cnt[51]; 7 int main() 8 { 9 int n,k,u,v,i,j; 10 scanf("%d",&n); 11 for(i=1;i<=n;i++) 12 { 13 scanf("%d",&cnt[i]); 14 for(j=1;j<=cnt[i];j++) 15 { 16 scanf("%d",&a[i][j]); 17 } 18 sort(a[i]+1,a[i]+cnt[i]+1); 19 } 20 scanf("%d",&k); 21 while(k--) 22 { 23 scanf("%d%d",&u,&v); 24 i=1,j=1;int sum=0,ans=0; 25 while(i<=cnt[u]&&j<=cnt[v]) 26 { 27 if(a[u][i]==a[v][j]) 28 { 29 ans++; 30 while(a[u][i+1]==a[u][i]&&i<=cnt[u]){ 31 i++; 32 } 33 while(a[v][j+1]==a[v][j]&&j<=cnt[v]){ 34 j++; 35 } 36 i++;j++; 37 } 38 else if(a[u][i]<a[v][j]) 39 { 40 while(a[u][i+1]==a[u][i]&&i<=cnt[u]){ 41 i++; 42 } 43 i++; 44 } 45 else if(a[u][i]>a[v][j]){ 46 while(a[v][j+1]==a[v][j]&&j<=cnt[v]){ 47 j++; 48 } 49 j++; 50 } 51 sum++; 52 } 53 if(cnt[u]>=i) sum+=cnt[u]-i+1; 54 if(cnt[v]>=j) sum+=cnt[v]-j+1; 55 printf("%.1f%%\n",100.0*ans/sum); 56 } 57 return 0; 58 }