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%%
",100.0*ans/sum);
56     }
57     return 0;
58 }
原文地址:https://www.cnblogs.com/L-King/p/5497042.html