2012 Multi-University Training Contest 4
If we have two sorted lists of integers A and B, we can easily find in linear time by keeping two pointers if there are a in A and b in B such that a+b=c (c is given).
Now, for this problem, we create a sorted list of all sums for S[0] and S[1] (call it M[0]), and a sorted list of all sums for S[2] and S[3] (call it M[1]). We can do this in O(n^2 log n).
Then, for each member c of S[4], we find if there's a in M[0] and b in M[1] such that a+b+c=0 using the method described in paragraph one. Sinc each search takes O(n^2) time (because the size of lists are O(n^2)), and we have O(n) members in S[4], total time complexity of this algorithm will be O(n^3).
View Code
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define N 205 5 #define LL long long 6 7 LL a[N], b[N], c[N]; 8 LL sum1[N * N], sum2[N * N], m1, m2; 9 10 int main() 11 { 12 int t, n, i, j, k; 13 scanf("%d", &t); 14 while(t --) 15 { 16 scanf("%d", &n); 17 for(i = 0; i < n; i ++) 18 scanf("%I64d", &a[i]); 19 for(i = 0; i < n; i ++) 20 scanf("%I64d", &b[i]); 21 22 m1 = 0; 23 for(i = 0; i < n; i ++) 24 for(j = 0; j < n; j ++) 25 sum1[m1 ++] = a[i] + b[j]; 26 27 for(i = 0; i < n; i ++) 28 scanf("%I64d", &a[i]); 29 for(i = 0; i < n; i ++) 30 scanf("%I64d", &b[i]); 31 32 m2 = 0; 33 for(i = 0; i < n; i ++) 34 for(j = 0; j < n; j ++) 35 sum2[m2 ++] = a[i] + b[j]; 36 37 for(i = 0; i < n; i ++) 38 scanf("%I64d", &c[i]); 39 40 std::sort(sum1, sum1 + m1); 41 std::sort(sum2, sum2 + m2); 42 std::sort(c, c + n); 43 44 bool flag = false; 45 for(i = 0; i < n; i ++) 46 { 47 flag = false; 48 j = 0, k = m2 -1; 49 while(j < m1 && k >= 0) 50 { 51 LL v = -(sum1[j] + sum2[k]); 52 if(c[i] == v) 53 { 54 flag = true; 55 break; 56 } 57 else if(c[i] < v) 58 j ++; 59 else 60 k --; 61 } 62 if(flag) 63 break; 64 } 65 if(flag) 66 printf("Yes\n"); 67 else 68 printf("No\n"); 69 } 70 return 0; 71 }
概率/组合数学 + 容斥原理。设卡片的分布p=(p1,p2,...,pn)。则:
用二进制表示集合枚举实现。
View Code
1 #include <cstdio> 2 #include <cstring> 3 const int maxn = 20 + 2; 4 double p[maxn]; 5 int n, m; 6 7 double solve(int s) 8 { 9 double res = 0.0; 10 m = 0; 11 for(int i = 0; i < n; i ++) 12 if(s & (1 << i)) 13 res += p[i], m ++; 14 return 1.0 / res; 15 } 16 17 int main() 18 { 19 while(scanf("%d", &n) == 1) 20 { 21 for(int i = 0; i < n; i++) 22 scanf("%lf", &p[i]); 23 double ans = 0.0; 24 for(int s = 1; s < (1 << n); s++) 25 { 26 double t = solve(s); 27 ans += t * ((m & 1) ? 1 : -1); 28 } 29 printf("%lf\n", ans); 30 } 31 }
AKing...