二分已学,直接上代码模板
#include<bits/stdc++.h>
using namespace std;
int a[110];
int search(int a[],int x,int y)
{
int left=0,right=x-1;
while(left<=right)
{
int mid=(left+right)/2;
if(a[mid]>y) right=mid;
else if(a[mid]==y) return y;
else left=mid+1;
}
return -1;
}
int main()
{
int m,n,i,j;
cin>>m>>n;
for(i=0;i<m;i++)
cin>>a[i];
cout<<search(a,m,n);
return 0;
}
例题
题目描述
出题是一件痛苦的事情!
相同的题目看多了也会有审美疲劳,于是我舍弃了大家所熟悉的 A+B Problem,改用 A-B 了哈哈!
好吧,题目是这样的:给出一串数以及一个数字 CC,要求计算出所有 A - B = CA−B=C 的数对的个数(不同位置的数字一样的数对算不同的数对)。
输入格式
输入共两行。
第一行,两个整数 N, CN,C。
第二行,NN 个整数,作为要求处理的那串数。
输出格式
一行,表示该串数中包含的满足 A - B = CA−B=C 的数对的个数。
输入输出样例
输入 #1复制
4 1 1 1 2 3
输出 #1复制
3
说明/提示
对于 75\%75% 的数据,1 \leq N \leq 20001≤N≤2000。
对于 100\%100% 的数据,1 \leq N \leq 2 \times 10^51≤N≤2×105。
保证所有输入数据绝对值小于 2^{30}230,且 C \ge 1C≥1。
2017/4/29 新添数据两组
代码实现
#include<cstdio>
using namespace std;
int m,t,n,i,l,r,mid,w,q,a[5000000];
int main()
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++) scanf("%d",&a[i]);
for(i=1;i<=n;i++)
{
l=i+1;r=n;
while(l<=r)
{
mid=(l+r)/2;
if(a[i]+m<=a[mid])
r=mid-1;
else
l=mid+1;
}
w=l;//找出后面所指定连续数的第一位
l=i+1;r=n;
while(l<=r)
{
mid=(l+r)/2;
if(a[i]+m<a[mid])
r=mid-1;
else
l=mid+1;
}
q=l;//找出后面所指定连续数的末位+1
t+=q-w;//直接减出连续串的长度
}
printf("%d",t);
return 0;
}
原理说明
1234会产生六种可能。在六种可能里。寻找答案出现的次数
分巧克力代码实现
#include<bits/stdc++.h>
using namespace std;
const int c=2e5+10;
int n,k,h[c],w[c];
bool check(int m)
{
long long c=0;
for(int i=0;i<n;i++)
c+=(long long)(h[i]/m)*(w[i]/m);
if(c>=k)
return true;
return false;
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++)
scanf("%d%d",&h[i],&w[i]);
int ans=1;
int l=1,r=100000;
while(l<=r)
{
int m=l+(r-1)/2;
if(check(m))
{
ans=m;
l=m+1;
}
else r=m-1;
}
printf("%d",ans);
return 0;
}
原理说明
在答案可能出现的范围。用二分查找。慢慢缩小答案的范围。这找到正确答案。
三次根求解代码实现
#include<bits/stdc++.h>
using namespace std;
const double eps=1e-8;
double n;
int main()
{
cin>>n;
double l=-1e4,r=1e4;
while(r-l>eps)
{
double mid=(l+r)/2;
if(mid*mid*mid>=n)
r=mid-1e-7;
else
l=mid+1e-7;
}
printf("%.6lf",l);
return 0;
}
原理说明
与上体一直。精度范围改变
剪绳子代码实现
#include<bits/stdc++.h>
using namespace std;
const int c=1e5+10;
const double eps=1e-4;
int n,m;
int len[c];
bool check(double mid)
{
int ans=0;
for(int i=0;i<n;i++)
ans+=len[i]/mid;
if(ans>=m)
return true;
else return false;
}
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++)
scanf("%d",&len[i]);
double l=0,r=1e9;
while(r-l>eps)
{
double mid=(r+l)/2;
if(check(mid))
l=mid;
else r=mid;
}
printf("%.2f",l);
return 0;
}
原理说明
与上体一致。只是跨度更大。每次直接少一半。
模板