[C++] 2017联发科技杯编程挑战赛 复赛题 “杰克船长的烦恼”
题目如下。
规则
杰克船长这次运气不错,抢到了一大堆金币。但他马上又开始发愁了, 因为如何给大家分金币,一直都是件不容易的事,每次杰克船长都要头疼好几天。
关于分金币,海盗的行规是这样的:
- 每次行动,船长会根据各个海盗的表现记功,事后论功行赏,给大家分金币。
- 分战利品的时候,海盗们会随意的站成一排,船长给每个人发一袋金币。袋子里的金币数目有多有少,但船长保证每个海盗至少会分到一枚金币。
- 拿到金币后,相邻的两个海盗会互相比较。如果其中一个功劳高些,那他的金币必须多一些,如果两个人分数一样,他们的金币必须一样。否则,海盗们就觉得不公平,要闹事,甚至造反。
怎么样才能用最少的金币让大家都满意呢? 领导这帮海盗可不轻松。
听说这次比赛中有一位将来要成为海贼王的男人,杰克船长相信他一定能解决这个麻烦。
输入说明
在程序当前目录下存在execute.stdin文件,程序从execute.stdin中取得输入数据。
execute.stdin中存放着N(N<100)个十进制正整数,数字之间用空格格开。
每个数字都代表某个海盗的功劳,值范围为(1, 100)。
输出说明
输出一个正整数,代表让所有海盗都满意的最少的金币数。
算法思路
找出序列中所有的局部最小值,给对应位置的船员分配一枚金币,然后两侧的依次金币数加1。
在两个局部最小值之间有一个局部最大值,例如一段序列
... 11 12 13 14 12 11 ...
,若两侧的11是局部最小值,14是局部最大值,则从左往右,11到13的位置分别分配1 2 3枚金币;从右往左,11到12的位置分别分配1 2枚金币,14的位置如果分配3枚金币的话不能满足比13多的条件,所以14的位置分配4个金币。所以,从两侧的局部最小值依次递增到局部最大值位置的时候,局部最大值对应位置取较大的金币数。对于序列的最左和最右位置,如果第一个数小于/大于第二个数,则其是局部最小/大值;如果最后一个数小于/大于倒数第二个数,则其是局部最小/大值;
源代码
#include <iostream>
#include <fstream>
#include <vector>
using std::vector;
// vector作为函数参数和返回值表示法
void money(const vector <int> & value);
vector <int> findLocalMin(const vector <int> & vec);
int main()
{
/*打开文件,获取功劳值信息*/
std::ifstream file;
file.open("execute.stdin");
int temp;
vector <int> value; // 存储功劳值
if (!file)
{
std::cout << "Error!";
}
while (file >> temp)
{
value.push_back(temp);
}
file.close();
/*计算金币数*/
money(value);
//std::cin.get();
return 0;
}
void money(const vector <int> &value)
{
// 去除重复的数
int length = value.size();
vector <int> newValue;
newValue.push_back(value[0]);
for (int i = 1; i < length; ++i)
{
if (value[i] != value[i - 1])
{
newValue.push_back(value[i]); // 抽取不重复的数
}
}
// 找局部最小值位置
vector <int> minLocalPos = findLocalMin(newValue);
// 分配金币(对应不重复的序列)
int len = newValue.size();
vector <int> gold; // 放置金币(对应原始序列)
vector <int> newGold(len, 1); // 放置金币(对应不重复的序列)
if (minLocalPos[0] > 0) // 刚开始是递减
{
for (int k = minLocalPos[0] - 1; k >= 0; --k)
{
newGold[k] = newGold[k+1] + 1; // 在后一个的基础上加一
}
}
for (int i = 1; i < minLocalPos.size(); ++i)
{
for (int j = minLocalPos[i - 1] + 1; j < minLocalPos[i]; ++j) //从前往后
{
if (newValue[j] > newValue[j - 1])
{
newGold[j] = newGold[j-1] + 1; // 在前一个的基础上加一
}
}
for (int j = minLocalPos[i] - 1; j > minLocalPos[i - 1]; --j) //从后往前
{
// 如果此方向的梯度更大
if ((newValue[j] > newValue[j + 1]) && (newGold[j + 1]+1 > newGold[j]))
{
newGold[j] = newGold[j + 1] + 1; // 在后一个的基础上加一
}
}
}
int end = minLocalPos[minLocalPos.size() - 1];
if (len - 1 > end) // 末尾是单调增的
{
for (int i = end + 1; i < len; ++i)
{
newGold[i] = newGold[i - 1] + 1; // 在前一个的基础上加一
}
}
/*for (int k = 0; k < newGold.size(); ++k)
{
std::cout << newGold[k] << " ";
}*/
// 分配金币(对应原始的value序列)
int j = 0;
int i = 0;
while(i < length)
{
if (value[i] == newValue[j])
{
gold.push_back(newGold[j]);
++i;
}
else
{
++j;
}
}
// 计算金币和
int sum = 0;
for (int k = 0; k < gold.size(); ++k)
{
//std::cout << gold[k] << " ";
sum += gold[k];
}
std::cout << sum;
}
// 找局部最小值的位置
vector <int> findLocalMin(const vector <int> & vec)
{
vector <int> minLocalPos;
int len = vec.size();
if (len == 1)
{
minLocalPos.push_back(0);
return minLocalPos;
}
// len >= 2
if (vec[0] < vec[1])
{
minLocalPos.push_back(0);
}
for (int i = 1; i < len - 1; ++i)
{
if ((vec[i] < vec[i - 1]) && (vec[i] < vec[i + 1]))
{
minLocalPos.push_back(i);
}
}
if (vec[len - 1] < vec[len - 2])
{
minLocalPos.push_back(len - 1);
}
return minLocalPos;
}
运行结果
[C++] 2017联发科技杯编程挑战赛 复赛题 “杰克船长的烦恼”的更多相关文章
- 2017湖湘杯复赛writeup
2017湖湘杯复赛writeup 队伍名:China H.L.B 队伍同时在打 X-NUCA 和 湖湘杯的比赛,再加上周末周末周末啊,陪女朋友逛街吃饭看电影啊.所以精力有点分散,做出来部分题目,现在 ...
- hdu 4542 数论 + 约数个数相关 腾讯编程马拉松复赛
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4542 小明系列故事--未知剩余系 Time Limit: 500/200 MS (Java/Others) ...
- 2017"百度之星"程序设计大赛 - 复赛1005&&HDU 6148 Valley Numer【数位dp】
Valley Numer Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- 2017"百度之星"程序设计大赛 - 复赛1003&&HDU 6146 Pokémon GO【数学,递推,dp】
Pokémon GO Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- 2017"百度之星"程序设计大赛 - 复赛1001&&HDU 6144 Arithmetic of Bomb【java大模拟】
Arithmetic of Bomb Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- 2017"百度之星"程序设计大赛 - 复赛 01,03,05
Arithmetic of Bomb Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- 2017年蓝桥杯B组C/C++决赛题解
2017年蓝桥杯B组C/C++决赛题目(不含答案) 1.36进制 ok 求36进制,类比二进制转10进制,36^3 + 36^2 + 36^1 + 36^0 2.磁砖样式 ok dfs搜索 我自己写的 ...
- 2017年蓝桥杯B组C/C++决赛题目
2017年第八届蓝桥杯B组C/C++决赛题目 点击查看2017年蓝桥杯B组C/C++决赛题解 1.36进制 对于16进制,我们使用字母A-F来表示10及以上的数字. 如法炮制,一直用到字母Z, ...
- 第四届蓝桥杯 c/c++真题
第四届蓝桥杯 c/c++真题 <1>高斯日记 问题 大数学家高斯有个好习惯:无论如何都要记日记. 他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210 后来人们 ...
随机推荐
- poj 2662(Dijkstra+记忆化)
题目链接:http://poj.org/problem?id=2662 思路:首先路径的选择,如果B点到终点的距离比A点到终点的最短距离短,那么就从A走到B,换句话说,就是每次都是择优选择更靠近终点的 ...
- Flash Builder 相关
1.Flex SDK 4.1 兼容性 Flex SDK 4.1 兼容 Flash Builder 4.0 ,因此在 Flash Builder 4.0 中使用 4.1 SDK 时可以使用设计视图 Fl ...
- ViewPager滑动引导页
ViewPager实现Animation动画引导页 http://blog.csdn.net/ye_scofield/article/details/44831357 SurfaceView实现动 ...
- 提高SDN控制器拓扑发现性能
原文由我发表在sdnlab.com.原文链接:http://www.sdnlab.com/15425.html SDN网络的一大特点就是资源由控制器集中管理,控制器管理网络,最基本的当然需要知道网络的 ...
- window下搭建python开发环境
搭建一个python开发环境比较简单,所以就稍微记录一下. 1.下载python然后安装 2.配置环境变量 3.在eclipse添加PyDev插件 1.下载python 官网:https://www. ...
- 模块化之SeaJS(二)
Seajs 此文来自 予舍驿站 提供简单.极致的模块化开发体验 非官方文档,整理来自己官方文档的文字与实例,方便速查. seajs.configObject aliasObject 别名配置,配置之后 ...
- SpringMVC 返回的 json 中去除某些不必要的属性
修改返回的Model,在对应的属性的get方法上使用 com.fasterxml.jackson.annotation.JsonIgnore 注解即可. 如 @JsonIgnore(true) pub ...
- Linux基础命令(四)
作业一:1) 开启Linux系统前添加一块大小为15G的SCSI硬盘 [root@bogon ~]# fdisk -l Disk /dev/sda: 21.5 GB, 21474836480 byte ...
- QStorageInfo获取磁盘信息(非常详细)
QStorageInfo类提供了系统当前挂载的存储和驱动器的相关信息,包括它们的空间,挂载点,标签名,文件系统名. 一般,我们可以使用特定的文件或目录来创建一个QStorageInfo类的对象,也可以 ...
- Oracle 11g数据库详解(2)
FAILED_LOGIN_ATTEMPTS 用于指定连续登陆失败的最大次数 达到最大次数后,用户会被锁定,登陆时提示ORA-28000 UNLIMITED为不限制 精确无误差 是 实时 PASSWOR ...