二分法入门(二)——POJ 3258,2976;HDU 4430;CodeForces 535C;Gym 101194D;ACdream 1066
来源:互联网 发布:历史api数据后原油波动 编辑:程序博客网 时间:2024/06/04 21:28
1.Bet ACdream - 1066
题意就是每次赌博有不同的可以买(买大买小这样的),每种有自己的赔率(赢了的回报为投入的钱y*回报率a[i]),每次赌博只能有一种是有回报的,要你求出最坏情况回报最大的值,策略就是把总金额y分成y[1],y[2],y[3]….使得y[1]*a[1]==y[2]*a[2]==……这样不论是哪一种获得回报你都会得到相同的回报,二分答案,然后判断钱能不能这样买。
#include<stdio.h>#include<algorithm>#include<iostream>using namespace std;double r,l,mid;int n;double money;double c[105];int main(){ while(~scanf("%d",&n)){ for(int i=0;i<n;i++){scanf("%lf",&c[i]);} scanf("%lf",&money); l=0,r=100000; while(r-l>0.00001){ mid=(l+r)/2; double cnt=0; for(int i=0;i<n;i++){ cnt+=mid/c[i]; } if(cnt>money){r=mid;} else{l=mid;} } printf("%.2lf\n",mid); } return 0;}
River Hopscotch POJ - 3258
最大化最小值,二分题里很经典的一种了,跳石子,删去一些石子使得跳跃距离的最小值最大,最后一块不能删(起点和终点)。
#include<stdio.h>#include<string.h>#include<algorithm>#include<string>#include<iostream>using namespace std;int l,n,m;int lef,righ,mid;int a[50050];int main(){ while(~scanf("%d%d%d",&l,&n,&m)){ lef=0,righ=1000000001; for(int i=00;i<n;i++){ scanf("%d",&a[i]); } a[n]=l; sort(a,a+n+1); while(righ-lef>1){ int mid=(righ+lef)/2; int cnt=0,used=0; bool yes=1; for(int i=0;i<=n;i++){ if(a[i]-cnt<mid){ if(i==n||used==m){yes=0;break;} else{used++;} } else{cnt=a[i];} } if(yes){lef=mid;} else{righ=mid;} } printf("%d\n",lef); } return 0;}
Dropping tests POJ - 2976
–
之前写过很类似的题,最大化平均值,通常策略就是二分答案再依据答案排序贪心选择,判断能不能满足mid。
#include<stdio.h>#include<string.h>#include<algorithm>#include<string>#include<iostream>using namespace std;int n,m;double lef,righ,mid;int a[1005],b[1005];double c[1005];bool cmp(double a,double b){return a>b;}int main(){ while(scanf("%d%d",&n,&m),m+n){ m=n-m; lef=0,righ=100; for(int i=0;i<n;i++){ scanf("%d",&a[i]); } for(int i=0;i<n;i++){ scanf("%d",&b[i]); } for(int k=0;k<100;k++){ mid=(righ+lef)/2; for(int i=0;i<n;i++){ c[i]=(double)a[i]*1.0*100-(double)b[i]*1.0*mid; } sort(c,c+n,cmp); double cnt=0; for(int i=0;i<m;i++){ cnt+=c[i]; } if(cnt>=0){lef=mid;} else{righ=mid;} } printf("%.0lf\n",mid); } return 0;}
Yukari’s Birthday HDU - 4430
以同心圆的方式给生日蛋糕插蜡烛,总共r圈,最内圈为b支蜡烛的情况下,第i圈插的蜡烛的数量为b^i,数量不能多也不能少,圆心可以插一根蜡烛也可以不插,求r*b的最小值。
因为蜡烛每一圈数量增长的速度非常快,所以r到50就足够满足数据范围了,枚举r然后寻找对应的b的最小值就行。
#include<iostream>#include<string.h>#include<stdio.h>#include<string>#include<vector>#include<algorithm>#include<queue>using namespace std;long long n;long long r, lk, rk, midk;int main(){ while (cin >> n){ n; long long ss = n - 1, a_r = 1, a_k = n - 1; for (int r = 2; r <= 50 && r <= n; r++){ lk = 1; rk = 1000001; bool yes = 0; while (rk - lk > 1){ midk = (rk + lk) / 2; long long cnt = 1; long long ans = 0; for (int i = 1; i <= r; i++){ ans += (cnt *= midk); if (ans > n)break; } if (ans == n || ans == n - 1){ yes=1; rk = midk; break; } if (ans > n){ rk = midk; } else{ lk = midk; } } if (yes){ if (r*rk < ss || (r*rk == ss&&r < a_r)){ ss = r*rk; a_r = r; a_k = rk; } } } cout << a_r << " " << a_k << endl; } return 0;}
Tavas and Karafs CodeForces - 535C
#include<iostream>#include<stdio.h>#include<algorithm>using namespace std;long long A, B, n;long long l, t, m;int main(){ while (cin>>A>>B>>n){ for (int k = 0; k < n; k++){ cin >> l >> t >> m; if (t < (A + (l - 1)*B)){ printf("-1\n"); } else{ long long beg = l, endd = (t - A) / B + 2; while (endd - beg>1){ long long mid = (beg + endd) / 2; long long cnt = m*t; long long sss = ((A + (l - 1)*B) + (A + (mid - 1)*B))*(mid - l + 1) / 2; if (cnt >= sss){ beg = mid; } else{ endd = mid; } } printf("%d\n", beg); } } } return 0;}
Ice Cream Tower Gym - 101194D
–
构造冰淇凌塔需要下面一块是上面的两倍以上,给出n个冰淇凌球,要求塔高为k,问能构造出多少个冰淇凌塔,排序,二分可以构造出来的数量,然后贪心判断结果,我用的优先队列,先把前mid个球加入队列作为mid个塔的顶,然后顺序遍历数组,每次就与优先队列的top(塔高最小且最下面的球的面积最小)的比较能否满足,满足就pop队列顶然后push({s,h+1})进去,这是一种比较直观的做法,但是跑出来时间有点久,其实判断满足mid的时候也可以lower_bound当前球两杯大小来寻找,速度更快。
#include<iostream>#include<string.h>#include<stdio.h>#include<string>#include<algorithm>#include<queue>using namespace std;int n, k;long long b[300005];struct ice{ long long maxn; int h; bool operator <(const ice b)const{ if (h == b.h){ return maxn>b.maxn; } return h > b.h; }};priority_queue<ice> que;int main(){ int t; scanf("%d", &t); for(int cas=1;cas<=t;cas++){ //cin >> n >> k; scanf("%d%d", &n, &k); for (int i = 0; i < n; i++){ cin >> b[i]; //scanf("%lld", &b[i]); } sort(b, b + n); int beg = 0, endd = n / k+3; while (endd - beg>1){ int mid = (endd + beg) / 2;//totalnum for (int i = 0; i < mid&&i<n; i++){ que.push({ b[i], 1 }); } for (int i = mid; i < n; i++){ ice cnt = que.top(); if (b[i] >= 2 * cnt.maxn){ que.pop(); que.push({ b[i], cnt.h + 1 }); } } int total = 0; while (!que.empty()){ if (que.top().h >= k)total++; que.pop(); } if (total < mid){ endd = mid; } else{ beg = mid; } } cout << "Case #" << cas << ": " << beg << endl; } return 0;}
- 二分法入门(二)——POJ 3258,2976;HDU 4430;CodeForces 535C;Gym 101194D;ACdream 1066
- CodeForces - 448D—Multiplication Table--二分法(nlogn)
- Codeforces Gym 100642 C D F
- CodeForces Gym 100735D
- CodeForces Gym 100989C 1D Cafeteria (A)
- Gym 100917D dir -C(RMQ)
- codeforces GYM 101431D(构造)
- Codeforces Gym 101485D Debugging
- Codeforces Gym 101164 C. Castle (KMP)
- CodeForces Gym 100114C
- CodeForces Gym 100735C
- codeforces Gym-101246C
- Codeforces gym 101243 C
- 【二分法】codeforces 460C
- Codeforces 801C 二分法
- Codeforces GYM 100651 D I Conduit! (水计算几何)
- Codeforces Gym 101164 D. Reading Digits (模拟)
- Codeforces Gym 101174 D. Dinner Bet (期望 + DP)
- 华为P8桌面上的短信图标不见了怎么办
- offsetleft和style.left的区别
- Dynamics CRM 2015-Form之添加Ribbon Button
- 重建二叉树
- MACOS: 如何在应用程序中应用文件超链接,直接打开文件
- 二分法入门(二)——POJ 3258,2976;HDU 4430;CodeForces 535C;Gym 101194D;ACdream 1066
- Unity3d中UnassignedReferenceException: The variable target of Moving has not been assigned. You proba
- StringBuffer和StringBuilder的区别
- Linux虚拟机环境搭建所遇到的问题
- C++ 长整型数据的输出
- 网页安全测试
- AXI4、AXI4-Lite、AXI-Stream总线协议的简单认识
- 如何提取iOS App素材
- Codeforces Gym 100962 H. Hans Zimmer