- 二分法
//示例算法输出的是下标
#include <iostream>
using namespace std;
template<class Type>
int BinarySearch(Type a[],const Type& x,int n){
int left, right, mid;
left = 0;
right = n - 1;
while(left <= right){
mid = (left + right) / 2;
if(x == a[mid])
return mid;
if(x < a[mid])
right = mid - 1;
else
left = mid + 1;
}
return -1;
}
int main(){
int n, x;
cin >> n >> x;
int a[n];
for(int i = 0; i < n; i++)
cin >> a[i];
cout << BinarySearch(a, x, n);
}
输入样例:
5 2
1 2 3 4 5
输出样例:
1
- 改写二分算法
#include <iostream>
using namespace std;
void biSearch(int x, int a[], int left, int right) {
if (left > right) { //当数组中没有元素时
cout << right << " " << left << endl; //①left为0,right为0 - 1 即为-1
//②right = mid - 1就是目标位置的左边
//left = mid + 1就是目标位置的右边
return;
}
int middle = (left + right) / 2;
if (a[middle] == x) {
cout << middle << " " << middle << endl;
return;
}
else if (a[middle] > x)
return biSearch(x, a, left, middle - 1);
else
return biSearch(x, a, middle + 1, right);
}
int main() {
int n;
int x;
cin >> n >> x;
int a[n];
for(int i = 0; i < n; i++)
cin >> a[i];
biSearch(x, a, 0, n - 1);
}
输入格式:
输入有两行:
第一行是n值和x值; 第二行是n个不相同的整数组成的非降序序列,每个整数之间以空格分隔。
输出格式:
输出小于x的最大元素的最大下标i和大于x的最小元素的最小下标j。当搜索元素在数组中时,i和j相同。 提示:若x小于全部数值,则输出:-1 0 若x大于全部数值,则输出:n-1的值 n的值
输入样例:
6 5
2 4 6 8 10 12
输出样例:
1 2
- 求逆序对数目
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
void merge_sort(long long left, long long right);
void merge(long long left, long long middle, long long rith);
long long nums[100002], tmps[100002], cnt = 0;
int main(){
long long n;
cin >> n;
memset(nums, 0, sizeof(nums)); //相当于定义数组
memset(tmps, 0, sizeof(tmps));
for(long long i = 1; i <= n; i++)
scanf("%lld", &nums[i]);
merge_sort(1, n);
printf("%lld\n", cnt);
}
void merge_sort(long long left, long long right){
long long mid;
if(left == right) return;
mid = (left + right) / 2;
merge_sort(left, mid);
merge_sort(mid + 1, right);
merge(left, mid, right);
}
void merge(long long left, long long mid, long long right){
long long i, j, k;
i = left;
j = mid + 1;
k = left; //左右两个小问题汇集到大问题后,还要再进行一次排序
while(i <= mid && j <= right){
if(nums[i] > nums[j]){
e cnt += j - k;
tmps[k++] = nums[j++]; //无论是j++,还是i++,都产生左移,用k++统一记录
}
else
tmps[k++] = nums[i++];
}
while(i <= mid) tmps[k++] = nums[i++];
while(j <= right) tmps[k++] = nums[j++];
for(i = left; i <= right; i++)
nums[i] = tmps[i];
}