猫史档案馆


还是C++【捂脸】

用户:青柠檬_肉乎乎的兔子青柠檬_肉乎乎的兔子查看:5 回复:1 评论:5 创建时间:2020-09-06T17:01:08


会做的大神帮帮忙,做对了我给你全部作品点赞(づ ̄3 ̄)づ╭❤~

一共三道题

--------------------------------------------

天梯排行变形问题

给定大小为n的数组,且数组内元素从小到大排列,求数组中与指定位置元素相同的所有元素的数量。

输入描述

输入共 3 行

第一行 一个整数 n,表示数组中有n个整数
第二行 n 个整数,以空格分开

第三行 数组中第 m 个整数

数据范围 n,m < 1000

输出描述

输出一个整数,表示第 m 个元素的数量。

输入样例

5
2 3 3 6 6
4

输出样例

2


-----------------------------------------


天梯排行

题目描述

n名玩家参加炉石传说竞技模式的比赛,到月末根据输赢成绩确定在天梯榜的级别,每名玩家的级别从低到高排序组成数组,可能会有多个人处于同一级别,求哪一个级别人数最多?

你可以假设n>=1,给定的数组内元素从小到大排列,且一定存在一个数量最多的元素,称为众数。

输入描述

输入共 2 行

第一行 一个整数 n,表示数组中有n名玩家的级别
第二行 n 个整数,分别表示n个玩家的级别

数据范围 n < 1000

输出描述

输出一个整数,表示 n 个整数中数量最多的数。

输入样例

3
2 3 3

输出样例

3

-------------------------------------------------

最大子段和(分治)

题目描述

N 个整数组成的序列a[1],a[2],a[3], ... ,a[n], 求该序列如a[i]+a[i+1]+...+a[j]的连续子段和的最大值。 当所给的整数均为负数时输出0。

例如:-2, 11, -4, 13, -5, -2,
最大的子段为:11, -4, 13,和为 20。

输入描述

输入共 2 行
第一行 一个正整数 n,代表序列的长度
第二行 n个整数,表示序列内的 n个整数

输出描述

输出一个整数,表示数组中最大的子段和

输入样例

9
-2 1 -3 4 -1 2 1 -5 4

输出样例

6

解题策略: 求解数组中下标范围在[x,y)之间最大子段和。

设 mid = (x+y)/2,可以将最大子段和分为三种情况:

  1. 最大子段和 在[x,mid) 这个范围内

  2. 最大子段和 在[mid,y) 这个范围内

  3. 最大子段和 横跨[x,mid) 和 [mid,y) 这两个区间

-----------------------------------------------

在线等啊啊啊啊啊


回复

上一页1 页 / 共 1下一页
急_开_锁_办_证810864急_开_锁_办_证810864

天梯排行:

#include <iostream>

int main(){
	int qsize; //数据规模
	int lastNum = -1, lastCnt = 0, currNum; //上一个处理的级别编号、上一个级别编号的出现次数、当前处理的级别编号
	int maxNum, maxCnt = 0; //记录出现最多的级别编号和对应次数

	cin >> qsize; //读取数据规模

	for(int i = 1; i <= qsize; i++){ //依次读取各个具体的级别编号
		cin >> currNum; //每次读取1个数

		if(currNum != lastNum){ //如果发现正在处理的是1个新级别编号
			//检查是否需要更新最大数量记录
			if(lastCnt > maxCnt){ //如果上一个编号的出现次数超过了最大已知值
				maxCnt = lastCnt;
				maxNum = lastNum;
			}

			//用当前的信息及时更新上一个信息
			lastNum = currNum;
			lastCnt = 1; //当前的计数值变为1
		}else{ //如果发现正在处理的是1个旧级别编号
			lastCnt++; //直接让当前的计数值递增
		}
	}

	//结束数据输入的循环后,还需要检查一次是否需要更新最大数量记录,保证最后1个级别编号也参与次数比较
	if(lastCnt > maxCnt){ //如果上一个编号的出现次数超过了最大已知值
		maxCnt = lastCnt;
		maxNum = lastNum;
	}

	cout << maxNum; //输出结果

	return 0;
}

天梯排行变形问题:

#include <iostream>

int main(){
	int qsize, qpos; //数据规模、最后所问级别编号的位置
	int nums[1001], cnts[1001]; //记录各个不同的级别编号和对应次数
	int lastIdx = 0, currNum; //上一个处理的级别编号的索引、当前新输入的级别编号

	cin >> qsize; //读取数据规模

	nums[lastIdx] = -0x3f; //先将第一个编号取为一个数据中不会出现的很大的负数
	for(int i = 1; i <= qsize; i++){ //依次读取各个具体的级别编号
		cin >> currNum; //每次读取1个数

		if(currNum != nums[lastIdx]){ //如果发现正在处理的是1个新级别编号
			//用当前的信息及时更新上一个信息
			lastIdx++;
			nums[lastIdx] = currNum;
			cnts[lastIdx] = 1; //当前的计数值变为1
		}else{ //如果发现正在处理的是1个旧级别编号
			cnts[lastIdx]++; //直接让当前的计数值递增
		}
	}

	cin >> qpos;
	for(int i = 1; i <= lastIdx; i++){ //有效编号从0开始
		qpos -= cnts[i]; //每次向后数若干个相同的数,即将位置序号减去前几个数的出现次数
		if(qpos <= 0){ //如果位置的值一直减到了0
			cout << cnts[i]; //输出结果
            break; //不必继续循环
		}
	}

	return 0;
}

最大子段和(分治):

#include <iostream>
using namespace std;

int arr[1000];

int findAns(int beginPos, int endPos){ //注意只取左端点,不取右端点
	if(endPos - beginPos <= 1){ //如果左右两侧间距太小
		return arr[beginPos];
	}

	int midPos = (beginPos + endPos) / 2; //计算中点位置

	int leftVal = findAns(beginPos, midPos); //只向左递归查找
	int rightVal = findAns(midPos, endPos); //只向右递归查找

	int maxVal = leftVal > rightVal ? leftVal : rightVal; //当前已知的最大值

	//查找横跨左右两侧的区间
	for(int i = beginPos; i < midPos; i++){ //确定子区间的可能左端点
		for(int j = midPos; j <= endPos; j++){ //确定子区间的可能右端点
			if(i == beginPos && j == endPos){ //最后再单独考虑整个区间的情形,避免无限递归
				continue;
			}

			int spanVal = findAns(i, j); //递归查找
			if(spanVal > maxVal){ //如果可以更新最大值
				maxVal = spanVal;
			}
		}
	}

	//单独处理整个区间本身的情况
	int wholeVal = 0;
	for(int i = beginPos; i < endPos; i++){
		wholeVal += arr[i];
	}
	if(wholeVal > maxVal){ //如果可以更新最大值
		maxVal = wholeVal;
	}

	return maxVal;
}

int main(){
	int qsize; //问题规模

	cin >> qsize;
	for(int i = 1; i <= qsize; i++){
		cin >> arr[i]; //依次读取各个具体值
	}

	cout << findAns(1, qsize + 1); //在索引范围[1, qsize + 1)内查找并输出结果

	return 0;
}

点赞就不必了。话说今天教师节,你可以考虑给你们老师冲点Q币,让他们周末打游戏练级也爽一爽惹。

center_image

点赞1


评论