关于二分的查找我们已经见过了许多,在另一篇博客:http://blog.csdn.net/thearcticocean/article/details/50408776 中用PYTHON写过相关的代码。现在记录两题,也是那种非“==”的二分查找。
nefu 610 小郑吃面条
http://acm.nefu.edu.cn/JudgeOnline/problemshow.php?problem_id=610
小郑喜欢吃面条,但是他吃的面条总是每根长度都相同因为他好像有强迫症。但是郑妈妈擀出面条长短是不一样的。小郑每次吃面条前都要告诉郑妈妈吃多少根,然后郑妈妈用刀将擀完的面条切成小郑要求的根数,为了让小郑吃多一些,郑妈妈每次都会把面条切得尽可能长。现在给你m根长短不一的面条,小郑想吃面条的根数n以及m根面条的各自长度,请你帮帮小郑算一下这顿饭他能吃到的面条最长有多长。(两根面条不能接在一起)
分析:寻找">=“关系的二分
#include <iostream> #include <cstdio> using namespace std; const int N=1e4+10; int m,n,x[N]; int midfind(int val){ int l=1,r=val,mid,ans=val; while(l<=r){ mid=(l+r)>>1; int sum=0; for(int i=0;i<m;i++){ sum+=x[i]/mid; } if(sum>=n){ ans=mid; l=mid+1; } else r=mid-1; } return ans; } int main() { while(cin>>m>>n){ int Max=0; for(int i=0;i<m;i++){ scanf("%d",&x[i]); Max=max(Max,x[i]); } printf("%d\n",midfind(Max)); } return 0; }
http://codeforces.com/problemset/problem/302/B
大意:听N首歌,每一首歌有自己的次数和每次听的时间,给出时间问正在停哪一首歌?
#include <iostream> #include <cstdio> using namespace std; const int N=1e5+10; int f[N]; int n,m; int midfind(int key){ //寻找大于等于的最小dex int l=1,r=n,mid,ans=0; while(l<=r){ mid=(l+r)>>1; if(f[mid]<key){ ans=mid; l=mid+1; } else r=mid-1; } return ans+1; } int main() { //freopen("cin.txt","r",stdin); int c,t,q; while(cin>>n>>m){ for(int i=1;i<=n;i++){ scanf("%d%d",&c,&t); f[i]=f[i-1]+c*t; } for(int i=0;i<m;i++){ scanf("%d",&q); printf("%d\n",midfind(q)); } } return 0; }
啊,这题倒是“==”型的二分查找,但是原数组不是从小到大的排列
nefu 611 找自己
http://acm.nefu.edu.cn/JudgeOnline/problemshow.php?problem_id=611
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int N=5e5+10; int n,m; int a[N]; int cmp(int p1,int p2){ return p1>p2; } int midfind(int val){ int l=0,r=n-1,mid,ans=0; while(l<=r){ mid=(l+r)>>1; if(a[mid]==val){ ans=mid+1; break; } else if(a[mid]>val){ l=mid+1; } else r=mid-1; } return ans; } int main() { while(cin>>n>>m){ for(int i=0;i<n;i++) scanf("%d",&a[i]); sort(a,a+n,cmp); int x; for(int i=0;i<m;i++){ scanf("%d",&x); printf("%d\n",midfind(x)); } } return 0; }