关注
受到杨超度同学思路的启发,我觉得这道题可以这样想,需要一个先验知识:X轴上有N个点,求X轴上一点使它到这N个点的距离之和最小。那么根据中位数性质,这个点一定是这组数中的中位数(该性质的简单证明可以参考https://blog.csdn.net/sm_545/article/details/78196351)。 这道题在先验知识的基础上有两个变形,首先题目要求是环,那么我们就在这N个数后面再补上N个数(其中新加的N个数分别是前N个数加环的长度L)然后我们从中截取N段,使得每段都包含了所有的数,分别对每段应用先验知识;其次题目要求移动到相邻位置,那就在先验知识的基础上减去一个常数即可。因为一旦N给定,这个常数就确定了(具体求法见下方代码) public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int result = Integer.MAX_VALUE;
int L = sc.nextInt(); //项链的长度
int N = sc.nextInt(); //珍珠的个数
int[] nums = new int[2*N+1]; //存拓展后的珍珠位置编号
int m, constant = 0;
m = (N+1) / 2;
for(int i = 1; i <= N ; i++){
nums[i] = sc.nextInt();
constant += Math.abs(m - i); //求先验知识和本题差的那个常数
}
Arrays.sort(nums, 1, N+1); //排序前N个数
for(int i = N+1; i <=2*N; i++) {
nums[i] = nums[i - N] + L; //拓展,补上N个数
}
for(int left = 1; left <= N; left++){ //截取N段,每段包含了所有的珍珠
int answer = 0; //按照先验知识求的距离和
int right = left + N-1;
int i = left, j = right;
while(i <= j){
answer += nums[j--] - nums[i++];
}
result = Math.min(answer - constant, result);
}
System.out.println(result);
}
查看原帖
点赞 1
相关推荐
投票
点赞 评论 收藏
分享
点赞 评论 收藏
分享
牛客热帖
更多
正在热议
更多
# xx岗简历求拷打 #
1907次浏览 22人参与
# 金三银四,你有感觉到吗 #
687856次浏览 6071人参与
# 有转正机会的小厂实习值得去吗? #
2809次浏览 39人参与
# 携程求职进展汇总 #
874816次浏览 5679人参与
# 你最讨厌面试被问什么 #
3975次浏览 46人参与
# 哪些公司开春招了? #
29078次浏览 192人参与
# 秋招踩过的“雷”,希望你别再踩 #
187075次浏览 1694人参与
# 机械制造2024笔面经 #
1540536次浏览 13005人参与
# 毕业季等于分手季吗 #
54475次浏览 649人参与
# 牛客租房专区 #
157406次浏览 1779人参与
# 26届的你,投了哪些公司? #
256401次浏览 1686人参与
# 文科生还参加今年的春招吗 #
13034次浏览 98人参与
# 找实习多的是你不知道的事 #
1805508次浏览 20691人参与
# 反问环节如何提问 #
132022次浏览 2702人参与
# 大家每天通勤多久? #
86935次浏览 855人参与
# 记录实习开销 #
188011次浏览 990人参与
# 校招笔试 #
417776次浏览 2797人参与
# 找工作中的小确幸 #
81499次浏览 452人参与
# 正在实习的你,几点下班 #
300496次浏览 2229人参与
# 如何缓解入职前的焦虑 #
261376次浏览 1466人参与
