本文共 3309 字,大约阅读时间需要 11 分钟。
只知道数据结构的一点皮毛,突然听说有个PAT考试,不管有用没用先报名了,还有一个整月,抱一本《算法笔记》压压惊,祝福我自己>_<。
有时遇到二分问题时脑子不清醒,停止的条件和左右指针如何变化总是乱乱的。作者总结了一个模板。例如:
1). 从小到大排序的数列中,从左到右找第一个大于等于x的位置,条件可以设置为if(A[mid] >= x)
2). 从小到大排序的数列中,从左到右找到第一个大于x的位置,条件可以设置为
if(A[mid]>x)
3). 从大到小排序的数列中,找到最小的一个大于等于x的位置,即从右到左找到第一个大于等于x的位置。相当于从左到右寻找第一个小于x的位置并且-1。条件可以设置为
if(A[mid] < x)//最终返回值为return left -1;
模板为:
int solve(int left,int right){ int mid; mid = (left + right)/2; while(left < right){ if(条件成立){ right = mid; }else{ left = mid + 1; } return left;}
等价于
int solve(int left,int right){ int mid; mid = (left + right)/2; while(left +1< right){ if(条件成立){ right = mid; }else{ left = mid; } return right;}
int find(int A[],int left,int right,int x){ int mid; while(left <= right){ mid = (left + right)/2; if(A[mid] == x) return mid; else if (A[mid] >x){ right = mid-1; } else{ left = mid+1; } } return -1;}
两个具体的题目
#includeint sumk(int A[],int n,int l){ int re=0; for(int i=0;i
const double PI = acos(-1.0);const double eps = 1e-5;//求圆心角之和double totalCornerAngles(double edges[], int n, double r) { double sum = 0.0; for (int i = 0; i < n; i++) { sum += asin(edges[i] / r / 2) * 2; } return sum;}//2分求半径double radius(double A[],int n) { double left,right, mid; //最大线段的圆心角,剩余线段的圆心角和 double maxangle, other; //最大线段长 double maxedge = *max_element(A, A + n); //如果最大线段恰好是直径 double sum = totalCornerAngles(A, n, maxedge / 2); if (fabs(sum - PI) < eps) { return max_ridge / 2; } //半径应大于最大线段的一半 left = maxedge / 2, right = 100; //循环求解 while ((right - left) > eps) { mid = (left + right) / 2; maxangle = asin(maxedge / 2 / mid) * 2; sum = totalCornerAngles(A, n, mid); other = sum - maxangle; //如果其他圆心角之和小于pi,圆心在多边形外面 if (other < PI) { sum = other - maxangle + 2 * PI; if (fabs(sum - 2 * PI) < eps) { return mid; } else if (sum < 2 * PI) { left = mid; } else { right = mid; } } else { //否则在内部 if (fabs(sum - 2 * PI) < eps) { return mid; } else if (sum > 2 * PI) { left = mid; } else { right = mid; } } }}
转载地址:http://xeldz.baihongyu.com/