1.在有序的数组中查找某一个数(默认递增)
int BinaryFind(vector<int> &a,int left,int right,int x)
{
int mid;
while(left<=right)
{
mid=left+(right-left)/2;
if(a[mid]==x)
return mid;
else if(a[mid]>x)
{
left=mid+1;
}
else
{
left=right-1;
}
}
return -1;
}
2.寻找第一个大于等于x的元素的位置
int lower_bound(vector<int> a,int left,int right,int x)
{
int mid;
while(left<right)
{
mid=left+(right-left)/2;
if(a[mid]>=x)
{
right=mid;
}
else
{
left=mid+1;
}
}
return left;
}
3.求序列中第一个大于x的位置
//寻找第一个大于x的位置
int upper_bound(vector<int> a,int left,int right,int x)
{
int mid;
while(left<right)
{
mid=(left+right)/2;
if(a[mid]>x)
{
right=mid;
}
else
{
left=mid+1;
}
}
return left;
}
以上是寻找第一个大于等于x或者第一个大于x的模板。
如果求第一个小于x的位置,那么就是求第一个大于等于x的位置减1;
如果求第一个小于等于x的位置,求第一个大于x的位置减1
4.求根号2的近似值
求根号2的近似值,可以求f(x)=x^2接近于2的解
//已知f(x)=x^2计算根号2的近似值
double F(double x)
{
return x*x;
}
double count()
{
double left=1;
double right=2;
double mid;
while(right-left>1e-5)
{
mid=(left+right);
if(F(mid)>2)
{
right=mid;
}
else
left=mid;
}
return mid;
}
5.木棒切割问题
给一些木棒,求最少k段长度木棒的最大长度
随着长度的增加,木棒的段数越来越多,最少k段就是求最后一个使得段数大于等于k的最大长度
可以转换为求第一个使段数小于k的长度,最后减1即可
vector<int> a;
int cut(int len)
{
int k=0;
for(int i=0;i<a.size();i++)
{
k=k+a[i]/len;
}
return k;
}
int resolve(int x,int max_len)
{
int left=0;
int right=max_len;
int mid;
while(left<right)
{
mid=(left+right)/2;
if(cut(mid)<x)
{
right=mid;
}
else
{
left=mid+1;
}
}
return left-1;
}
6.快速幂(奇偶情况)
给定a b c
求a^b%c
ll llpow(ll a,ll b,ll c)//常规做法
{
ll ans=1;
for(int i=0;i<b;i++)
anw=anw*a%c;
return ans;
}
快速幂的思想是基于
若b为偶数 可以拆分为a^ b/2a^b/2
若a为奇数 可以拆分为a^1a ^b-1
递归写法
ll quickpow(ll a,ll b, ll c)
{
if(b==0) return 1;
if(b%2==0)
{
double ans=quickpow(a,b/2,c);
return ans*ans%c;
}
else
return a*quickpow(a,b-1,c)%c;
}
迭代写法:
a从1 2 4 开始增加,判断1 2 4是否存在,存在则乘以ans不存在,a继续扩大两倍
ll quickpow1(ll a,ll b,ll c)
{
ll anw=1;
while(b>0)
{
if(b&1==1)
{
anw=anw*a%c;
}
a=a*a%m;
b=b>>1;
}
return ans;
}
可以选择自己喜欢的形式
1085 Perfect Sequence
本题注意:
ou are supposed to find from the sequence as many numbers as possible to form a perfect subsequence.
这句话的意思是从这个队列中选择,也就是说,并不一定按照给定的顺序进行选择。
首先,我们对这个序列进行由小到大的排序,并且我们每一次默认固定一个数字为最小值,我们寻找第一个使得M>m*p的位置,返回left-1即可,
bool cmp(int a,int b)
{
return a<b;
}
ll n,q;
vector<ll> save;
ll Binary_solve(ll left,ll right)
{
ll k=left;
ll mid;
ll min=save[left];
ll p=min*q;
if(save[right]<=p) return right-k+1;//若一开始就满足
while(left<right)
{
mid=(left+right)/2;
if(save[mid]>p)
{
right=mid;
}
else
{
left=mid+1;
}
}
return left-k;
}
int main()
{
cin>>n>>q;
for(int i=0;i<n;i++)
{
int k;
scanf("%d",&k);
save.push_back(k);
}
sort(save.begin(),save.end(),cmp);
ll max=-1;
for(int i=0;i<n;i++)
{
ll anw=Binary_solve(i,n-1);
if(anw>max)
max=anw;
}
cout<<max<<endl;
1010 Radix
1044 Shopping in Mars