用户:
青柠檬_肉乎乎的兔子查看: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,可以将最大子段和分为三种情况:
最大子段和 在[x,mid) 这个范围内
最大子段和 在[mid,y) 这个范围内
最大子段和 横跨[x,mid) 和 [mid,y) 这两个区间
-----------------------------------------------
在线等啊啊啊啊啊
急_开_锁_办_证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币,让他们周末打游戏练级也爽一爽惹。

点赞1
评论