解题思路:
将兔子分为两种(1.它和它的同伴相向而行 2.它和它的同伴不相向而行)。不难发现最后兔子的位置都位于第一种(它和它的同伴相向而行)兔子最后的位置上。所以我们可以首先确定第一种兔子的最终位置----(该兔子开始的位置+它同伴的开始位置)/2向下取整。然后在根据第一种兔子的位置确定第二种兔子的位置(该兔子移动方向上最先遇到的第一种兔子的位置)
举例:
2 5 7 9 1
从小到大排序: 1 2 5 7 9
移动方向: 1 -1 1 -1 -1(-1表示往左,1表示往右)
确定第一种兔子位置:1 1 6 6 9
确定第二种兔子位置:1 1 6 6 6
还原: 1 6 6 6 1
注意事项:
参考代码:
#include <bits/stdc++.h>
using namespace std;
typedef struct
{
long long l; // 位置
long long n; // 编号
} Elem;
bool cmp(Elem a, Elem b)
{
return a.l < b.l;
}
int main()
{
long long N;
cin >> N;
vector<Elem> r(N);
for (long long i = 0; i < N; i++)
{
cin >> r[i].l;
r[i].n = i;
}
sort(r.begin(), r.end(), cmp);
vector<long long> d(N);
for (long long i = 1; i < N - 1; i++)
{
if (r[i].l - r[i - 1].l <= r[i + 1].l - r[i].l)
d[i] = -1; // 表示左边的是他的同伴
else
d[i] = 1; // 右边
}
d[0] = 1;
d[N - 1] = -1;
vector<long long> loc(N);
for (long long i = 0; i < N; i++)
loc[i] = r[i].l;
long long ok = 0;
for (long long i = 0; i < N; i++)
if (d[i] == 1 && d[i + 1] == -1) // 如果两个兔子相向而行
loc[i] = loc[i + d[i]] = (loc[i] + loc[i + d[i]]) / 2;
for (long long i = 0; i < N; i++)
{
if (!((d[i] == 1 && d[i + 1] == -1) || (d[i] == -1 && d[i - 1] == 1))) // 如果没有兔子与该相向而行
{
int k = i + d[i];
while (!(d[k] == d[i] && d[k + d[i]] == -d[i])) // 找到合适的位置
k = k + d[i];
loc[i] = loc[k];
}
r[i].l = loc[i];
}
unordered_map<long long, long long> location;
for (long long i = 0; i < N; i++)
location[r[i].n] = loc[i];
// 输出兔子位置
for (long long i = 0; i < N; i++)
cout << location[i] << " ";
return 0;
}0.0分
3 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复