HZNUOJ 2508:双峰插云
我们注意到总的颜色种类只有200,故我们可以先处理出所有云朵中每一种颜色有多少朵云朵拥有,此处我们约定用$cnt[] 表示$
然后暴力枚举将哪朵云分给老薛,记录三个临时变量$Max_{kk}, Max_{xuexue}, pos$
$分别表示kk能够得到的最大颜色种类数,薛薛能够得到的最大颜色种类数,以及分给薛薛的云朵的下标$
枚举的时候注意要优先满足$kk, 如果当前得到的Max_{kk} 和之前的一样,再考虑一下薛薛$
$关于枚举的时候如果得到除了当前云朵外其他云朵的总的颜色总数$
首先记录一下预处理的$cnt[]中一共有多少个 >= 1 的元素,记为res, 此处用数组下标表示云朵标号$
$那么在枚举云朵的时候,我们用tmp表示除了这朵云外还剩下多少种不同颜色,显然tmp = res - x$
$x 表示有几种颜色是只有这朵云拥有的$
$再枚举这朵云拥有的所有颜色,判断在cnt[] 中这种颜色是不是 刚好为1即可$
$注意到一朵云的颜色种类数最多只有10.$
$总的时间复杂度是O(10n)$
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define N 100010 6 7 int main() { 8 int a[N][11]; 9 int b[N]; 10 int f[210]; 11 int n, m, i, j, t, p; 12 scanf("%d%d",&n, &m); 13 memset(f, 0, sizeof f); 14 for (i = 1; i <= n; ++i) { 15 scanf("%d",&a[i][0]); 16 for (j = 1; j <= a[i][0]; ++j) { 17 scanf("%d",&a[i][j]); 18 f[a[i][j]]++; 19 } 20 } 21 for (i = 1; i <= n; ++i) { 22 b[i] = 0; 23 for (j = 1; j <= a[i][0]; ++j) 24 if (f[a[i][j]] == 1) 25 b[i]++; 26 } 27 t = 1; 28 for (i = 2; i <= n; ++i) 29 if (b[i] < b[t]) t = i; 30 else if (b[i] == b[t] && a[i][0] > a[t][0]) t = i; 31 puts("KK:"); 32 j = 1; 33 while (j == t) ++j; 34 printf("%d",j); 35 for (i = j + 1; i <= n; ++i) 36 if (i != t) 37 printf(" %d",i); 38 printf("\n"); 39 puts("Xuexue:"); 40 printf("%d\n",t); 41 return 0; 42 }