[] Data structure and algorithm study notes - "algorithm notes" -12 [dichotomy]

By sequential search method, the time complexity is O [n];
dichotomy of the time complexity is O [logn].

Example:
[n-] = {1,3,4,6,7,8,10,11,12,15} subscripts found in 6 and 9 A (failure -1)

#include "stdafx.h"
#include <cstdio>

int binaryS(int A[], int left, int right, int x)
{
	int mid;
	while (left <= right)
	{
		mid = (left + right) / 2;
		if (A[mid] < x)
			left = mid + 1;
		if (A[mid] > x)
			right = mid - 1;
		if (A[mid] == x)
			return mid;
	}
	return -1;
}

int main()
{
	int A[10] = { 1,3,4,6,7,8,10,11,12,15 };
	binaryS(A, 0, 9, 9);
	printf("%d\n%d\n", binaryS(A, 0, 9, 6), binaryS(A, 0, 9, 9));
	return 0;
}

Further question: if the element A is incremented sequence may be repeated, then how the position of a given element x To find out, to obtain a first sequence of element x greater than or equal to L and the first element is greater than x position R, so that the sequence element x in the presence of the left section is closed right open interval.

1 sub-problems:

//A[]为递增序列,x为欲查询的数,函数返回第一个大于等于x的元素的位置
//二分上下界为左闭右闭的[left,right],传入的初值为[0,n]
int lower_bound(int A[], int left, int right, int x)
{
	int mid;
	while (left < right)//left==right意味着找到唯一位置
	{
		mid = (left + right) / 2;
		if (A[mid] < x)
		{
			left = mid + 1;
		}
		else
		{
			right = mid;
		}
	}
	return left;//返回夹出来的位置
}

Sub Issue 2:

int upper_bound(int A[], int left, int right, int x)
{
	int mid;
	while (left < right)//left==right意味着找到唯一位置
	{
		mid = (left + right) / 2;
		if (A[mid] > x)
		{
			right = mid;
		}
		else
		{
			left = mid + 1;
		}
	}
	return left;//返回夹出来的位置
} 
		

Differences between the above two sub-problems in that only A [mid]> = 0 and A [mid]> 0 (i.e., the conditions to be met)
Resolve "to find an ordered sequence of elements in a position to meet the first condition" problem fixed template

Partition between two left and right opening and closing zone cycling conditions should be left + 1 <right, left + 1 = right there is established, so that the (left, right] is the only position to exit the loop. Since the opening into a left, left the minimum value is smaller than the initial value of a solution, for example, from the index for the zero sequence, left and right may be chosen to be n-1 and return right

Dichotomy seek prescribing

#include <cstdio>
#include <algorithm>
using namespace std;
double eps = 10e-5;

double f(double x)
{
	return x * x;
}

double calSqrt(double a, double b, double out)
{
	double left = a, right = b, mid;
	while (right - left > eps)						//控制精度
	{
		mid = (left + right) / 2;
		if (f(mid) < out)
			left = mid;
		else
			right = mid;
	}
	return mid;
}

Hold water problem
Here Insert Picture Description
f () / calh () is what I wrote, f0 () / solve () is an example of the book

#include <cstdio>
#include<math.h>
#include <algorithm>
using namespace std;
const double eps = 10e-5;
const double Pi = acos(-1.00);

double f(double R, double h)
{
	double L = sqrt(R*R - (R - h)*(R - h));
	double alpha = asin(L / R);
	//double alpha = r * pi;
	return (alpha * R*R / 2 - (R - h)*L / 2)*2;//Sr
}

double calh(double R, double r)
{
	double SR = R * R*Pi / 2, Sr;
	double left = 0, right = R, mid;
	double want = SR * r;
	while (right - left > eps)						//控制精度
	{
		mid = (left + right) / 2;
		if (f(R, mid) < want)
			left = mid;
		else
			right = mid;
	}
	return mid;
}

double f0(double R, double h)
{
	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;
	while (right - left > eps)
	{
		mid = (left + right) / 2;
		if (f0(R, mid) > r)
		{
			right = mid;
		}
		else {
			left = mid;
		}
	}
	return mid;
}
int main()
{
	double R, r;
	scanf("%lf%lf", &R, &r);
	printf("%lf\n%lf", calh(R,r),solve(R,r));
	return 0;
}

For expression A B % m, made for loop

for(int i = 0; i < b; i++)
{
	ans = ans * a % m;
}

Its time complexity is O (b);
Thought and half power (power quickly), its time complexity is O (logb)
Recursive wording

typedef long long LL;

//求a^b%m 递归写法
LL binaryPow(LL a, LL b, LL m)
{
	if (b == 0)	return 1;
	if (b % 2 == 0)
	{
		LL temp = binaryPow(a, b / 2, m);
		return temp * temp % m;
	}
	/*if (b % 2 != 0)*/
	else
	{
		LL temp = binaryPow(a, b - 1, m);
		return temp * a%m;
	}
}


int main()
{
	double R, r;
	scanf("%lf%lf", &R, &r);
	printf("%lf\n%lf", calh(R,r),solve(R,r));
	return 0;
}

In the above code, the condition if (b% 2 = = 1) may be used if (b & 1) in place, since the b & 1 for bit operation, it is determined b the last bit is 1, the flow returns 1 when b is odd. This approach can improve execution speed.
Note also that when b% 2 = 0 Do not return directly binaryPow (a, b / 2% m) * binaryPow (a, b / 2% m), result in increased complexity.
Details:

  • If a possible initially greater than or equal m, then let before entering a function of the modulo m
  • If m is 1, can be directly judged in the external function is 0;

The wording of Iteration
Here Insert Picture Description

typedef long long LL;

//快速幂的迭代写法
LL binaryPow(LL a, LL b, LL m)
{
	LL  temp = 1;
	while(b>0)
	{
		temp *= a * (b & 1) % m;
	/*	if (b & 1)
		{
			temp = a*temp % m;
		}*/
		b /= 2;
		a = a * a%m;
	}
	return temp;
}

exercise

Find x

Title Description
enter a number n, and then enter the n value is different, then a value of input x, the output value of the subscript in the array (from 0, if the array is output 1).
Input
test data set multiple, input n (1 <= n <= 200), then the number of inputs n, and the input x.
Output
for each set of input, output.
Sample input
. 4
. 1 2. 4. 3
. 3
Sample Output
2

#include <string>
#include <cstdio>
#include <algorithm>
using namespace std;


struct nu {
	int id;
	int num;
}a[210];

bool cmp(nu a, nu b)
{
	return a.num < b.num;
}

//找X
int main()
{
	int n;
	int x;
	int mid;
	int L, R;
	while (scanf("%d", &n) != EOF)
	{
		for (int i = 0; i < n; i++)
		{
			a[i].id = i;
			scanf("%d", &a[i].num);
		}
		scanf("%d", &x);
		sort(a, a + n, cmp);
		int left = 0, right = n;
		while (left<right)
		{
			mid = (left + right) / 2;
			if (a[mid].num >=x)
				right = mid;
			if(a[mid].num<x)
				left = mid+1;				
		}
		if (a[left].num == x)
		{
			L = left;
			//left = 0;
			//right = n;
			//while (left < right)
			//{
			//	mid = (left + right) / 2;
			//	if (a[mid].num > x)
			//	{
			//		right = mid;
			//	}
			//	else
			//	{
			//		left = mid + 1;
			//	}
			//}
			//R = left-1;
		//	for (int j = L; j <= R; j++)
		//	{
		//		printf("%d", a[j].id);
		//		if (j != R)
		//			printf(" ");
		//	}
		//	printf("\n");
			printf("%d\n", a[L].id);
		}
		else
			printf("-1\n");
	}
	return 0;
}

This problem do not know what went wrong

Seek

Description Title
input array length n of
the input array a [1 ... n]
input to find the number m of
input digital lookup b [1 ... m]
output Finding the YES or NO or YES NO.
Enter
input multiple sets of data.
Each set of n input, and then enter the integers n, m and then input, and then enter the integers m (1 <= m <= n <= 100).
Output
If YES output of the n array output or NO.
Sample input
. 6
. 3 2. 5. 4. 7. 8
2
. 3. 6
sample output
YES
NO

#include <string>
#include <cstdio>
#include <algorithm>
using namespace std;

void func(int a[],int b,int n)
{
	int left = 0, right = n-1;
	int mid;
	bool flag = false;
	while (left <= right)
	{
		mid = (left + right) / 2;
		if (b > a[mid])
			left = mid + 1;
		if(b< a[mid])
			right = mid - 1;
		if (b == a[mid])
		{
			flag = true;
			printf("YES\n");
			break;
		}
	}
	if (flag==false)
		printf("NO\n");
	return;
}

int main()
{
	int m, n;
	int forwardleft = 0;
	int a[110], b[110];
	while (scanf("%d", &n) != EOF)
	{
		for (int q = 0; q < n; q++)
			scanf("%d", &a[q]);
		sort(a, a + n);
		scanf("%d", &m);
		for (int q = 0; q < m; q++)
		{
			scanf("%d", &b[q]);
		}
		for (int q = 0; q < m; q++)
		{
			 func(a, b[q], n);
		}
	}
}
Published 43 original articles · won praise 4 · Views 1212

Guess you like

Origin blog.csdn.net/weixin_42176221/article/details/101514928