题目:
有a和b两个严格增序列,a和b元素相同称为交汇点。例子中 5,9,22为交汇点,在交汇点处可以切换路径。
从a或b首元素出发,求元素之和最大的一条路径。例子中1-3-5-7-8-9-18-19-22-28-40为元素和最大的一条路径a[] = {1,3,5,9,20,22,28,40};b[] = {5,7,8,9,18,19,22,27};
//题目:有a和b两个严格增序列,a和b元素相同称为交汇点。
//例子中 5,9,22为交汇点,在交汇点处可以切换路径。
//从a或b首元素出发,求元素之和最大的一条路径。
//例子中1-3-5-7-8-9-18-19-22-28-40为元素和最大的一条路径
//a[] = {1,3,5,9,20,22,28,40};b[] = {5,7,8,9,18,19,22,27};
#include <stdio.h>
struct intersection{
int *a;
int *b;
};
#define MAXLEN 50
int sum_array(struct intersection x, struct intersection x_next);
int array_max(int *a, int m, int *b ,int n)
{
int i;
int *pa = a; int *pb = b;
int k = 1;
int sum = 0;
struct intersection intersec[MAXLEN]; //存放交汇点指针
intersec[0].a = a - 1; //设第一个交汇点在首元素之前
intersec[0].b = b - 1;
for(i = 0; i < m; i++)
{
while((*pa > *pb) && (pb < b + n -1))
pb++;
if(*pa == *pb)
{
intersec[k].a = pa;
intersec[k].b = pb;
k++;
}
pa++;
if(pb == b + n - 1) //end of array b
break;
}
intersec[k].a = a + m; //设最后一个交汇点在末元素之后
intersec[k].b = b + n;
for(i = 0; i < k; i++)
{
sum += sum_array(intersec[i], intersec[i+1]); //a和b在两交汇点间的元素(不包含交汇点)分别求和,并取最大值
}
for(i = 1; i < k; i++)
{
sum += *(intersec[i].a);
printf("intersection:%d\n", *(intersec[i].a));
}
return sum;
}
int sum_array(struct intersection x, struct intersection x_next)
{
int *p;
int max;
int sum_A = 0; int sum_B = 0;
for(p = x.a + 1; p <=x_next.a - 1; p++)
sum_A += *p;
for(p = x.b + 1; p <=x_next.b - 1; p++)
sum_B += *p;
max = sum_A>sum_B? sum_A : sum_B;
return max;
}
int main(void)
{
int ret, i;
int m, n;
int a[] = {1,3,5,9,20,22,28,40,80,90,99};
int b[] = {5,7,8,9,18,19,22,27,41,43,90,96,98};
m =sizeof(a)/sizeof(int);
n =sizeof(b)/sizeof(int);
for (i = 0; i < m; ++i)
{
if(i == 0) printf("a[] = %d", a[i]);
else printf("-%d", a[i]);
}
printf("\n");
for (i = 0; i < n; ++i)
{
if(i == 0) printf("b[] = %d", b[i]);
else printf("-%d", b[i]);
}
printf("\n");
ret = array_max(a, m, b, n);
printf("\nmax = %d\n", ret);
return 0;
}