65,202
社区成员




#include <iostream>
using namespace std;
// 交换区间(同时交换上界与下界)
void swap(unsigned int*arr, size_t i, size_t j)
{
unsigned int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
tmp = arr[i+1];
arr[i+1] = arr[j+1];
arr[j+1] = tmp;
}
// 按偶数索引进行快速排序
void quick_sort(unsigned int* arr, size_t s, size_t e)
{
if (s>=e) return;
unsigned int key = arr[s];
size_t i = s;
size_t j = e-1;
while (i < j)
{
while (i < j && arr[j]>=key) j-=2;
swap(arr, i, j);
while (i < j && arr[i]<=key) i+=2;
swap(arr, i, j);
}
// 因为用的是size_t(unsigned int),所以需要额外的检查,避免溢出
if (i != s)
quick_sort(arr, s, i-1);
quick_sort(arr, i+2, e);
}
// 依次合并同一个序列中的两个相邻区间(例如A和B需要合并,则A置为空[0,0],B置为A+B)
void merge(unsigned int* arr, size_t s, size_t e)
{
if (s >= e-1) return;
size_t i = s;
size_t j = s+2;
while (j+1 <= e)
{
if (arr[i+1]>=arr[j])
{
// 置为i+j
arr[j] = arr[i];
arr[j+1] = (arr[i+1]>arr[j+1])?arr[i+1]:arr[j+1];
// 置空[0,0]
arr[i] = arr[i+1] = 0;
}
i += 2;
j += 2;
}
}
// 因为存在空区间[0,0],所以在移动指针时需要跳过,移动到下一个有效区间或者序列的尾部
void move_next(unsigned int* arr, size_t s, size_t e, size_t& i)
{
if (i < s) return;
i += 2;
while (i <= e-1 && 0 == arr[i] && 0 == arr[i+1]) i += 2;
}
size_t foo(unsigned int *a1, size_t al1, unsigned int* a2, size_t al2)
{
// 排序与合并
quick_sort(a1, 0, al1-1);
quick_sort(a2, 0, al2-1);
merge(a1, 0, al1-1);
merge(a2, 0, al2-1);
// 统计并集
size_t total = 0;
// i指向序列一,j指向序列二
size_t i = 0, j = 0;
// e1为序列一的末端,e2为序列二的末端
size_t e1 = al1-1, e2 = al2-1;
// 依次比较序列一和序列二中的对应区间,一共有六种情况出现
while (i+1 <= e1 && j+1 <= e2)
{
// 1. |i~~~~i+1| |j~~~~j+1|, 移动i至下一组
if (a1[i+1] < a2[j]) move_next(a1, 0, e1, i);
// 2. |j~~~~j+1| |i~~~~i+1|, 移动j至下一组
if (a2[j+1] < a1[i]) move_next(a2, 0, e2, j);
// 3. |j~~~|i~~~i+1|~~~j+1|, 累加total(arr1[i+1]-arr1[i]),移动i至下一组
if (a2[j] <= a1[i] && a1[i+1] <= a2[j+1])
{
total += (a1[i+1]-a1[i]);
move_next(a1, 0, e1, i);
}
// 4. |i~~~|j~~~j+1|~~~i+1|, 累加total(arr2[j+1]-arr2[j]),移动j至下一组
if (a1[i] <= a2[j] && a2[j+1] <= a1[i+1])
{
total += (a2[j+1]-a2[j]);
move_next(a2, 0, e2, j);
}
// 5. |i~~~|j~~~i+1|~~~j+1|, 累加total(arr1[i+1]-arr2[j]),移动i至下一组
if (a1[i] <= a2[j] && a2[j] <= a1[i+1] && a1[i+1] <= a2[j+1])
{
total += (a1[i+1]-a2[j]);
move_next(a1, 0, e1, i);
}
// 6. |j~~~|i~~~j+1|~~~i+1|, 累加total(arr2[j+1]-arr1[i]),移动j至下一组
if (a2[j] <= a1[i] && a1[i] <= a2[j+1] && a2[j+1] <= a1[i+1])
{
total += (a2[j+1]-a1[i]);
move_next(a2, 0, e2, j);
}
}
return total;
}
int main()
{
unsigned int arr1[] = {0,1,3,6,10,20};
unsigned int arr2[] = {0,1,20,50,4,5};
cout<<"Result = "<<foo(arr1, sizeof(arr1)/sizeof(int), arr2, sizeof(arr2)/sizeof(int))<<endl;
system("pause");
return 0;
};