-
在一个严格递增序列A中找到给定的数x,输出其在数组中的下标。
#include<stdio.h> #include<math.h> /* 在一个严格递增序列A中找到给定的数x,输出其在数组中的下标。 */ int a[10]={3,7,8,11,15,21,33,52,66,88};; int binsearch(int left, int right, int x) { while(left<=right) { // int mid = (left+right)/2; //有可能溢出 int mid = left + (right - left)/2; //替换 if(a[mid]==x) return mid; if(a[mid]<x) left = mid+1; if(a[mid]>x) right =mid-1; } return -1; } int main() { int x = 11; int index = binsearch(0,9,x); printf("%d在数组a中的下标为%d\n",x, index); }
-
如果递增序列A中的元素可能重复,那么如何对给定的欲查询元素x,求出序列中第一个大于等于x的元素的位置L以及第一个大于x的元素的位置R,这样元素x在序列中的存在区间就是左闭右开区间[L,R)。
#include<stdio.h> #include<math.h> /* 如果递增序列A中的元素可能重复,那么如何对给定的欲查询元素x,求出序列中 第一个大于等于x的元素的位置L以及第一个大于x的元素的位置R,这样 元素x在序列中的存在区间就是左闭右开区间[L,R) */ int a[10]={1,3,3,3,6}; //第一问:求序列中的第一个大于等于x的元素的位置. int binsearch_1(int left, int right, int x) { while(left<right) //对[left,right]来说,left==right意味着找到了唯一位置 { int mid = left + (right - left)/2; //取中间点 if(a[mid]>=x) right = mid; if(a[mid]<x) left = mid+1; } return left; // 返回夹住的位置 } //求序列中第一个大于x的元素的位置 int binsearch_2(int left, int right, int x) { while(left<right) //对[left,right]来说,left==right意味着找到了唯一位置 { int mid = left + (right - left)/2; //取中间点 if(a[mid]>x) right = mid; if(a[mid]<=x) //不同点 left = mid+1; } return left; } int main() { int x = 3; int l = binsearch_1(0,4,x); int r = binsearch_2(0,4,x); printf("[%d, %d]\n",l, r); }
-
计算
的近似值。
#include<stdio.h> const double eps = 1e-5; //精度为10^(-5) double f(double x){ //计算f(x) return x*x; } double calSqrt() { double left=1, right=2, mid; //[left,right]=[1,2] while(right - left > eps){ mid = (left + right) / 2; if(f(mid)>2){ right = mid; } else left = mid; } return mid; } int main() { printf("%.5lf\n",calSqrt()); } //运行结果:1.41421
-
给定一个定义在[L,R]上的单调函数f(x),求f(x)=0的根。
#include<stdio.h> /* 给定一个定义在[L,R]上的单调函数f(x),求f(x)=0的根。 假设函数f(x)在[L,R]上递增。 */ const double eps = 1e-5; //精度为10^(-5) double f(double x){ //计算f(x) return x*x-2; } double solve(double L, double R) { double left=L, right=R, mid; //[left,right]=[1,2] while(right - left > eps){ mid = (left + right) / 2; if(f(mid)>0){ right = mid; } else left = mid; } return mid; //所返回的当前mid值即为f(x)=0的根 } int main() { printf("%.5lf\n",solve(1,2)); } //运行结果:1.41421
-
装水问题:
#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
/*
装水问题
*/
const double PI = acos(-1.0);
const double eps = 1e-5; //精度为10^(-5)
double f(double R, double h){ //计算f(x)
double alpha = 2*acos((R-h)/R);
double L=2*sqrt(R*R-(R-h)*(R-h));
double s1 = alpha*R*R/2 - L*(R-h)/2;
double s2 = PI*R*R/2;
return s1/s2;
}
double solve(double R, double r)
{
double left=0, right=R, mid; //[left,right]=[1,2]
while(right - left > eps){
mid = (left + right) / 2;
double t = f(R,mid);
if(t>r){
right = mid;
}
else
left = mid;
}
return mid; //所返回的当前mid值即为f(x)=0的根
}
int main()
{
double R=10,r=0.5;
printf("%.4f\n",solve(R,r));
}
//运行结果:1.41421
6. 木棒切割问题: 给出N根木棒,长度均已知,现在希望通过切割它们来得到至少K段长度相等的木棒(长度必须是整数), 问这些长度相等的木棒最长能有多长。参考代码:https://blog.youkuaiyun.com/weixin_42717165/article/details/87161259
N = 3 K= 7
10 24 5
//运行结果 6
#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
//木棒切割问题
int main()
{
int N,K,a[3];
scanf("%d%d",&N,&K);
int right = 0; //保存最大长度
for(int i=0; i<N; i++)
{
scanf("%d",&a[i]);
if(a[i]>right)
right = a[i];
}
int left = 1;
right++;
//printf("%d\n",right);
while(left+1<right) //(left,right] ,left+1==right 意味着唯一位置即最后的位置
{
int mid = (left+right)/2;
int k=0;
for(int i=0; i<N; i++)
k+=a[i]/mid;
if(k<K) right = mid; //条件成立
else left = mid;
}
printf("%d\n",right-1);
return 0;
}
7 . 给出n个线段的长度,试将它们头尾(顺序任意)地组成一个凸多边形,使得凸多边形的外接圆的半径最大,求该最大半径。其中n不超过10^5,线段长度均不超过100.要求算法中不涉及坐标的计算。(待解决)
8. 快速幂
#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
/*
求a^b%m,递归写法
*/
typedef long long LL;
LL binpow(LL a, LL b, LL m){
if(b==0) return 1; //如果b为0,那么a^0=1
//b为奇数,转换为b-1
//b&1 位与操作,判断b的末位是否为1
if(b&1) return a*bin(a, b-1,m)%m;
else{ //b为偶数,转换为b/2
LL mul = binpow(a, b/2, m);
return mul*mul%m;
}
}
/*
求a^b%m,迭代写法
*/
LL binpow_1(LL a, LL b, LL m)
{
LL ans=1;
while( b > 0)
{
if(b & 1)
{
ans = ans * a % m;
}
a = a * a % m;//令a平方
b >>= 1; //右移,除2
}
return ans;
}
int main()
{
return 0;
}