01-复杂度3 二分查找 (20 分)
本题要求实现二分查找算法。
函数接口定义:
Position BinarySearch( List L, ElementType X );
其中List
结构定义如下:
typedef int Position;
typedef struct LNode *List;
struct LNode {
ElementType Data[MAXSIZE];
Position Last; /* 保存线性表中最后一个元素的位置 */
};
L
是用户传入的一个线性表,其中ElementType
元素可以通过>、==、<进行比较,并且题目保证传入的数据是递增有序的。函数BinarySearch
要查找X
在Data
中的位置,即数组下标(注意:元素从下标1开始存储)。找到则返回下标,否则返回一个特殊的失败标记NotFound
。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 10
#define NotFound 0
typedef int ElementType;
typedef int Position;
typedef struct LNode *List;
struct LNode {
ElementType Data[MAXSIZE];
Position Last; /* 保存线性表中最后一个元素的位置 */
};
List ReadInput(); /* 裁判实现,细节不表。元素从下标1开始存储 */
Position BinarySearch( List L, ElementType X );
int main()
{
List L;
ElementType X;
Position P;
L = ReadInput();
scanf("%d", &X);
P = BinarySearch( L, X );
printf("%d\n", P);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例1:
5
12 31 55 89 101
31
输出样例1:
2
输入样例2:
3
26 78 233
31
输出样例2:
0
鸣谢宁波大学 Eyre-lemon-郎俊杰 同学修
正原题!
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 10
#define NotFound 0
typedef int ElementType;
typedef int Position;
typedef struct LNode *List;
struct LNode {
ElementType Data[MAXSIZE];
Position Last; /* 保存线性表中最后一个元素的位置 */
};
List ReadInput(); /* 裁判实现,细节不表。元素从下标1开始存储 */
Position BinarySearch( List L, ElementType X );
int main()
{
List L;
ElementType X;
Position P;
L = ReadInput();
scanf("%d", &X);
P = BinarySearch( L, X );
printf("%d\n", P);
return 0;
}
/* 你的代码将被嵌在这里 */
Position BinarySearch( List L, ElementType X )
{
int Right=L->Last;
int Left=1;
int mid;
while(Left<=Right)
{
mid=Left+(Right-Left)/2;
if(L->Data[mid]==X)
{
return mid;
}
else if(L->Data[mid]>X)
{
Right=mid-1;
}
else if(L->Data[mid]<X)
{
Left=mid+1;
}
}
return NotFound;
}
List ReadInput()
{
int N;
scanf("%d",&N);
List L;
L=malloc(sizeof(struct LNode));
for(L->Last=1;L->Last<=N;L->Last++)
{
scanf("%d",&L->Data[L->Last]);
}
return L;
}
附上Read函数的写法
01-复杂度1 最大子列和问题 (20 分)
给定K个整数组成的序列{ N1, N2, ..., NK },“连续子列”被定义为{ Ni, Ni+1, ..., Nj },其中 1≤i≤j≤K。“最大子列和”则被定义为所有连续子列元素的和中最大者。例如给定序列{ -2, 11, -4, 13, -5, -2 },其连续子列{ 11, -4, 13 }有最大的和20。现要求你编写程序,计算给定整数序列的最大子列和。
本题旨在测试各种不同的算法在各种数据情况下的表现。各组测试数据特点如下:
- 数据1:与样例等价,测试基本正确性;
- 数据2:102个随机整数;
- 数据3:103个随机整数;
- 数据4:104个随机整数;
- 数据5:105个随机整数;
输入格式:
输入第1行给出正整数K (≤100000);第2行给出K个整数,其间以空格分隔。
输出格式:
在一行中输出最大子列和。如果序列中所有整数皆为负数,则输出0。
输入样例:
6
-2 11 -4 13 -5 -2
输出样例:
20
这个题就是最长子列和问题,我采用的是在线处理算法,这个算法的时间复杂度是O(n)线性时间复杂度,表现最好。
其实处理最长子列和问题的方法一般有两种,一种是分治的思想,一种就是在线处理。
首先讲解一下分治的思想,分治,分成两段,最长子列和可能是左边,可能是右边,可能是中间跨过中间线的那种。时间复杂度NlogN
具体推导
在线处理思想就是:只要子列和大于零,他就可以继续走下去,有成为最大子列和的可能。只要他小于零就不可能,一定要归零,从新开始。
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int main()
{
int N;
cin>>N;
int array[N];
for(int i=0;i<N;i++)
{
cin>>array[i];
}
//在线处理;
int ThisSum=0;
int MaxSum=0;
for(int i=0;i<N;i++)
{
ThisSum+=array[i];
if(ThisSum>MaxSum)
MaxSum=ThisSum;
else if(ThisSum<0)
ThisSum=0;
}
cout<<MaxSum;
return 0;
}