大一寒假集训 二分入门
A - Cable master HDU - 1551
题目大意:求最大长度,使得每段铁丝截得的段数等于给出的k值。
1 #include<algorithm> 2 #include <iostream> 3 #include<cstdio> 4 #include<cmath> 5 #include<cmath> 6 using namespace std; 7 const int maxn = 100000 + 15; 8 double arr[maxn]; 9 int n, k; 10 bool solve(double mid) { 11 long long int ans = 0; 12 for (int i = 0;i < n;i++) { 13 ans =ans+(int)(arr[i] / mid); 14 } 15 if (ans >= k)return true; 16 else return false; 17 } 18 int main() { 19 while (scanf("%d %d", &n, &k), n + k) { 20 double max = 0; 21 for (int i = 0;i < n;i++) { 22 scanf("%lf", &arr[i]); 23 if (arr[i] > max)max = arr[i]; 24 } 25 double left = 0, right = max, mid; 26 while (right-left>1e-5) { 27 mid = (right + left) / 2; 28 if (solve(mid)) { left = mid; } 29 else right = mid; 30 } 31 printf("%.2f\n", left);//注意是left,因为mid不一定满足 32 } 33 34 return 0; 35 }
B - Dating with girls(1) HDU - 2578
题目大意:求给出数列中任意选两数之和为k的对数。前后可以交换。
1 #include<algorithm> 2 #include <iostream> 3 #include<cstdio> 4 #include<cmath> 5 #include<cmath> 6 using namespace std; 7 const int maxn = 100000 + 15; 8 int n, k; 9 int arr[maxn]; 10 int main() { 11 int t; 12 scanf("%d", &t); 13 while (t--) { 14 scanf("%d %d", &n, &k); 15 for (int i = 0;i < n;i++) { 16 scanf("%d", &arr[i]); 17 } 18 sort(arr, arr + n); 19 int num = unique(arr, arr + n) - arr;//去重 20 int ans = 0; 21 for (int i = 0;i < num;i++) { 22 int need = k - arr[i]; 23 if (2 * arr[i] == k) { ans++;break; } 24 else if (2 * arr[i] > k) { break; } 25 int left = i, right = num - 1, mid; 26 while (right >= left) { 27 mid = (right + left) / 2; 28 if (arr[mid] < need)left = mid + 1; 29 else if(arr[mid] > need)right = mid - 1; 30 else if (arr[mid] == need) { ans+=2;break; } 31 } 32 } 33 printf("%d\n", ans); 34 } 35 return 0; 36 }
C - Pie POJ - 3122 简单的二分,π是坑点
题目大意:给出蛋糕半径,分蛋糕,且每人份只能取自一个蛋糕。
1 #include<algorithm> 2 #include <iostream> 3 #include<cstdio> 4 #include<cmath> 5 #include<cmath> 6 #define pi acos(-1) 7 using namespace std; 8 const int maxn = 100000 + 15; 9 int n, f; 10 double arr[maxn]; 11 bool solve(double mid) { 12 int ans = 0; 13 for (int i = 0;i < n;i++) { 14 ans +=(int)(arr[i] / mid); 15 } 16 if (ans >= f + 1)return true; 17 else return false; 18 } 19 int main() { 20 int t; 21 scanf("%d", &t); 22 while (t--) { 23 double left = 0, right=0, mid; 24 scanf("%d %d", &n, &f); 25 for (int i = 0;i < n;i++) { 26 scanf("%lf", &arr[i]); 27 arr[i] = arr[i] * arr[i] * pi; 28 if (arr[i] > right)right =arr[i]; 29 } 30 while (right - left > 1e-5) { 31 mid = (right + left) / 2; 32 if (solve(mid))left = mid; 33 else right = mid; 34 } 35 printf("%.4f\n", left); 36 37 } 38 return 0; 39 }
D - Can you solve this equation? HDU - 2199
1 #include <iostream> 2 #include <map> 3 #include <string> 4 #include<algorithm> 5 #include<vector> 6 #include<cmath> 7 #define max 100010 8 using namespace std; 9 int a[max]; 10 double judge(double x){ 11 return 8 * x * x * x * x + 7 * x * x * x + 2 * x * x + 3 * x + 6 ; 12 } 13 int main() 14 { 15 int t; 16 scanf("%d", &t); 17 while (t--) { 18 long long int y; 19 scanf("%d", &y); 20 if (y < 0)y = -y; 21 double left = 0, right = 100; 22 int flag = 0; 23 double mid; 24 while (right >left) { 25 mid = (left + right) / 2; 26 if (fabs(judge(mid) - y) < 1e-5) { 27 flag = 1;break; 28 } 29 if (judge(mid) - y > 0)right = mid; 30 else left = mid; 31 } 32 if (flag == 0)printf("No solution!\n"); 33 else printf("%.4f\n", mid); 34 } 35 }
E - Rikka with Mutex HDU - 6261 二分,strlen放在for循环中会超时
题目大意:给定一串字符串由V和P组成,一个人的初始生命值为0,遇V+1,遇P-1,同伴中可以分享生命值,在保证生命值不为负的情况下,求最少需要多少人,能让一个人走到终点。
1 #include <iostream> 2 #include <cstdio> 3 #include<cstring> 4 using namespace std; 5 const int maxn = 1e5 + 10; 6 char str[maxn]; 7 bool solve(int mid) { 8 int life = 0, step = 0; 9 int len = strlen(str); 10 for (int i = 0;i < len;i++) { 11 if (str[i] == 'P') { step--;} 12 else step++; 13 if (step > 0) { 14 step = 0;life += mid;; 15 } 16 if (life+step< 0)return false; 17 } 18 return true; 19 } 20 int main() { 21 int t; 22 scanf("%d", &t); 23 while (t--) { 24 scanf("%s", str); 25 int len = strlen(str); 26 if (str[0] == 'P') { printf("-1\n");continue; } 27 int left = 0, right = len, mid; 28 int ans; 29 while (right >= left) { 30 mid = (left + right) / 2; 31 if (solve(mid)) { 32 ans = mid;right = mid - 1; 33 } 34 else left = mid + 1; 35 } 36 printf("%d\n", ans); 37 } 38 return 0; 39 }
F - Aggressive cows POJ - 2456 二分
题目大意:给出n个牛舍坐标(在一直线上),然后有m个牛要入住,现在问相邻牛之间的最小距离最大是几 ,通俗的说就是一条线段上有 n 个点,选取 m 个点,使得相邻点之间的最小距离值最大。
1 #include <iostream> 2 #include <map> 3 #include<cstdio> 4 #include <string> 5 #include<algorithm> 6 #include<vector> 7 #include<cmath> 8 #define maxn 100010 9 int arr[maxn],b[maxn],bj=0,n,c; 10 using namespace std; 11 bool solve(int mid) { 12 int cnt = 0,add=0; 13 for (int i = 0;i < bj;i++) { 14 add += b[i]; 15 if (add >= mid) { cnt++;add = 0; } 16 } 17 if (cnt >= c - 1)return true; 18 return false; 19 } 20 int main() 21 { 22 scanf("%d %d", &n, &c); 23 for (int i = 0;i < n;i++) { 24 scanf("%d", &arr[i]); 25 } 26 sort(arr, arr + n); 27 int right = 0; 28 for (int i = 1;i < n;i++) { 29 b[bj++] = arr[i] - arr[i - 1]; 30 right += b[bj - 1]; 31 } 32 int left = 0, mid,res; 33 while (right >= left) { 34 mid = (right + left) / 2; 35 if (solve(mid)) { 36 res = mid;left = mid + 1; 37 } 38 else right = mid - 1; 39 } 40 printf("%d\n", res); 41 }
G - 4 Values whose Sum is 0 POJ - 2785
题目大意:每列选一个看能否组成和为0.
1 #include <iostream> 2 #include <map> 3 #include <string> 4 #include<algorithm> 5 #include<vector> 6 #include<cstdio> 7 #include<cmath> 8 using namespace std; 9 vector<int>a,b,c,d,e,f; 10 int main() 11 { 12 int n; 13 scanf("%d", &n); 14 for (int i = 0;i < n;i++) { 15 int a1, b1, c1, d1; 16 scanf("%d %d %d %d", &a1, &b1, &c1, &d1); 17 a.push_back(a1);b.push_back(b1);c.push_back(c1);d.push_back(d1); 18 } 19 for (int i = 0;i < n;i++) { for (int j = 0;j < n;j++) { e.push_back(a[i] + b[j]); } } 20 for (int i = 0;i < n;i++) { for (int j = 0;j < n;j++) { f.push_back(c[i] + d[j]); } } 21 sort(f.begin(), f.end()); 22 int cnt = 0; 23 for (int i = 0;i < e.size();i++) { 24 int left = 0, right = f.size()-1, mid; 25 while (right >= left) { 26 mid = (left + right) / 2; 27 if (e[i] + f[mid] > 0)right = mid - 1; 28 else if (e[i] + f[mid] < 0)left = mid + 1; 29 else { 30 cnt++; 31 for (int j = mid + 1;j < f.size();j++) { 32 if (e[i] + f[j] == 0) { cnt++; } 33 else break; 34 } 35 for (int j = mid - 1;j >= 0;j--) { 36 if (e[i] + f[j] == 0) { cnt++; } 37 else break; 38 } 39 break; 40 } 41 } 42 } 43 printf("%d\n", cnt); 44 }

浙公网安备 33010602011771号