2019/9/20 中国大学mooc数据结构——浙大 第一节课代码总汇与总结

编程作业

01-复杂度1 最大子列和问题 (20 point(s))

此题为课上所讲的内容,为了让同学们感受四种算法的运算速度,PTA也专门为此设置超大上限的time limited。
原题链接
下面给出在线处理算法,即最快的算法。

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int main() {
	int number = 0;
	int TargetNumber = 0, MaxNubmer = 0, thisSum = 0;
	cin >> number;
	int target[100010] = { 0 };
	for (int i = 0; i < number; i++) {
		scanf("%d", &target[i]);
		thisSum += target[i];
		if (thisSum < 0) {
			thisSum = 0;
			continue;
		}
		if (MaxNubmer < thisSum)
			MaxNubmer = thisSum;
	}
	cout << MaxNubmer;
	return 0;
}

主要思路是:将输入的数据从1开始不断累加,不断地判断是否为Max。当发现累加的结果小于零时,可以发现如果继续累加,只会使结果越小,此时抛弃前面累加的结果,从下一个重新开始。

01-复杂度2 Maximum Subsequence Sum (25 point(s))

此题为上一题的进化版,要记录序列的起始位置和终点位置,同时也挖了很多的小坑。
原题连接
下面给出我自己的accept代码。

#include<stdio.h>
#include<iostream>
using namespace std;
int main() {
	int start = 0, end = 0, t = 0;
	int thisSum = 0, MaxSum = -1;
	int target[100010] = { 0 };
	int number = 0;
	bool flag = false;
	cin >> number;
	end = number - 1;
	for (int i = 0; i < number; i++) {
		scanf("%d", &target[i]);
		thisSum += target[i];
		if (MaxSum < thisSum) {
			MaxSum = thisSum;
			start = t;
			end = i;
			flag = true;
		}
		else if (thisSum < 0) {
			thisSum = 0;
			t = i + 1;
		}
	}if (MaxSum == -1)
		cout << "0" << " " << target[0] << " " << target[number - 1] << endl;
	else
		cout << MaxSum << " " << target[start] << " " << target[end] << endl;
	
}

要注意的点:

  1. 可能只有我犯了这一个错误,但这的确卡了我很久!没有看完题(或者没有看懂)就开始瞎输出了!我一开始看到输出样例为1 4,再扫一眼题目,嗯,大概是输出序列的首位和末尾的下标的意思……然后就看到一堆绿绿的wrong answer不知所措……注意了,是输出目标序列的第一位数据和最后一位数据!
  2. 测试点5:0和负数。倘若有零和负数,我们要输出最大为零和零的位置。如果令Max=0,会捕捉不到数据为0的情况,这样程序有可能会视其为测试点4去处理,但其实是不同的。
  3. 记得判断Max值是否发生改变!不去判断的话测试点4的最大值将不会输出为0而为-1。

01-复杂度3 二分查找 (20 point(s))

此题为二分查找,比较简单。
原题链接
下面给出我的accept代码。

Position BinarySearch(List L, ElementType X) {
	int left = 1, right = L->Last, mid = 0;
	while (left <= right) {
		mid = (left + right) / 2;
		if (L->Data[mid] > X)
			right = mid - 1;
		else if (L->Data[mid] < X)
			left = mid + 1;
		else
			return mid;
	}
	return NotFound;
}

要注意的点:

  1. 题目说数据为递增数列,则当中间值大于目标值时,应移动right边界,反之,应移动left边界。
  2. 因为只要判断出中间值时大于或者小于目标时,就能说明该点不是目标点,所以移动边界时,记得是right-1或者left+1.
  3. 判断条件记得是要left<=right。因为有可能判断到left=right时才确定结果,所以要等俩边界错位再跳出循环。

总结

  1. 审清题意,再动手。大部分时间都纠结在了那个非常弱智的坑里……明明很快就能ac掉的东西……
  2. 边界条件是很爱挖的坑,以后再刷pat的时候,多积累经验,再不给提示的情况下多琢磨可能出现的边界条件。
Roman wasn’t built in a day.Just do it.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值