标签:
给我们n,m , m表示茶壶的容量
接下来2*n个数字,表示茶杯的容量,将这些茶杯分给n个男孩和n个女孩
可以倒x毫升的茶水给每个女孩,那么就要倒2x毫升的茶水给男孩,当然了,茶杯要装的下,且茶壶的水足够多
问最多能倒多少毫升?
思路:将茶杯按容量从下到大排序,那么前n个茶杯一定分给女孩,后n个茶杯分给男孩。那么只要将第一个茶杯的容量作为上界,0作为下界,二分枚举x,
每次统计后n个茶杯的容量是不是>=2x,如果是,那么说明该容量是可行的。 但是最终的数据测试却错了, 因为精度要达到1e-11才能正确,不知道为什么
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <algorithm> 5 #include <iostream> 6 #include <queue> 7 #include <stack> 8 #include <vector> 9 #include <map> 10 #include <set> 11 #include <string> 12 #include <math.h> 13 using namespace std; 14 #pragma warning(disable:4996) 15 typedef long long LL; 16 const int INF = 1<<30; 17 const double eps = 1e-11; 18 /* 19 20 21 */ 22 int a[200000 + 10]; 23 int main() 24 { 25 int n, w; 26 while (scanf("%d%d", &n,&w) != EOF) 27 { 28 int m = 2 * n; 29 for (int i = 0; i < m; ++i) 30 { 31 scanf("%d", &a[i]); 32 } 33 sort(a, a + m); 34 double low = 0, high = a[0], mid; 35 int cnt; 36 double tmp; 37 while (high - low >= eps) 38 { 39 mid = (high + low) / 2; 40 cnt = 0; 41 for (int i = 0; i < m; ++i) 42 if (mid * 2 <= a[i]) 43 cnt++; 44 if (cnt >= n) 45 { 46 tmp = mid * 3 * n; 47 if (tmp<w) 48 high = mid; 49 else 50 low = mid; 51 } 52 else 53 high = mid; 54 } 55 printf("%f\n", mid * 3 * n); 56 57 } 58 return 0; 59 }
比完看了别人代码才知道,有更简单的方法, 只要去w/3/n, a[0], a[n]/2 的最小值就好了
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <algorithm> 5 #include <iostream> 6 #include <queue> 7 #include <stack> 8 #include <vector> 9 #include <map> 10 #include <set> 11 #include <string> 12 #include <math.h> 13 using namespace std; 14 #pragma warning(disable:4996) 15 typedef long long LL; 16 const int INF = 1<<30; 17 const double eps = 1e-11; 18 /* 19 20 21 */ 22 int a[200000 + 10]; 23 int main() 24 { 25 int n, w; 26 double ans = 0; 27 while (scanf("%d%d", &n,&w) != EOF) 28 { 29 int m = 2 * n; 30 for (int i = 0; i < m; ++i) 31 { 32 scanf("%d", &a[i]); 33 } 34 sort(a, a + m); 35 ans = (double)w / 3 / n; 36 ans = min(ans, (double)a[0]); 37 ans = min(ans, (double)a[n] / 2); 38 printf("%lf", ans*3*n); 39 } 40 return 0; 41 }
给我们n,表示有n条桌腿,
然后接下来n个数字,Li表示桌腿的长度,
再接下来n个数组,di表示砍掉第i的桌腿的费用。
一个桌子要是稳定的,要求桌子最长的桌腿的条数占总条数的一半以上
问使得桌子稳定的最小花费
思路:将桌腿按长度排序,然后遍历桌腿,枚举桌腿的长度x作为最长的桌腿,那么比x长的桌腿应该去掉,
比x长的桌腿都排在x后面,所以我们可以维护一个后缀和,使得可以在O(1)的时间内获得砍掉比x长的所有桌腿的费用
设长度为x的桌腿有cnt条,那么要将比x短的桌腿砍掉剩下cnt-1条即可。 砍的时候,肯定是先砍费用小的。
比赛时的想法是用优先队列维护一个费用队列,队头的费用最小。但是时间复杂度超了(不去算算法的时间复杂度果然是不好的习惯)
其实费用的取值是1-->200,所以只要用个标记数组来标记,每次只要遍历标记数组就可以了。
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <algorithm> 5 #include <iostream> 6 #include <queue> 7 #include <stack> 8 #include <vector> 9 #include <map> 10 #include <set> 11 #include <string> 12 #include <math.h> 13 #include <functional> 14 using namespace std; 15 #pragma warning(disable:4996) 16 typedef long long LL; 17 const int INF = 1<<30; 18 /* 19 20 */ 21 const int N = 100000 + 10; 22 struct Node 23 { 24 int l, d; 25 bool operator<(const Node&rhs)const 26 { 27 return l < rhs.l; 28 } 29 }a[N]; 30 int suffix[N],c[N]; 31 void input(int &x) 32 { 33 char ch = getchar(); 34 while (ch < ‘0‘ || ch>‘9‘) 35 ch = getchar(); 36 x = 0; 37 while (ch >= ‘0‘ && ch <= ‘9‘) 38 { 39 x = x * 10 + ch - ‘0‘; 40 ch = getchar(); 41 } 42 } 43 int main() 44 { 45 int n, i, j, ans, k, total; 46 while (scanf("%d", &n)!=EOF) 47 { 48 total = 0; 49 for (i = 0; i < n; ++i) 50 input(a[i].l); 51 for ( i = 0; i < n; ++i) 52 input(a[i].d); 53 54 sort(a, a + n); 55 for (i = 0; i < n; ++i) 56 suffix[i] = a[i].d; 57 for (i = n - 2; i >= 0; --i) 58 suffix[i] += suffix[i + 1]; 59 i = 0; 60 ans = INF; 61 while (i < n) 62 { 63 int tmp = a[i].l; 64 j = i; 65 while (i < n && a[i].l == tmp) 66 i++; 67 int cnt = i - j; 68 tmp = 0; 69 //砍掉比x更长的桌腿 70 if (i<n) 71 tmp = suffix[i]; 72 //total统计的是比x短的桌腿条数 73 int t = total; 74 75 for (k = 1; k <= 200; ++k) 76 { 77 if (t < cnt) 78 break; 79 if (t - c[k] >= cnt - 1) 80 { 81 tmp += c[k] * k; 82 t -= c[k]; 83 } 84 else 85 { 86 tmp += k * (t - cnt + 1); 87 break; 88 } 89 } 90 91 for (k = j; k < i; ++k) 92 { 93 c[a[k].d]++; 94 total++; 95 } 96 ans = min(ans, tmp); 97 } 98 printf("%d\n", ans); 99 } 100 return 0; 101 }
标签:
原文地址:http://www.cnblogs.com/justPassBy/p/4612395.html