L2-017 人以群分 Java题解

2023-10-20 12:59
文章标签 java 题解 l2 017 人以群分

本文主要是介绍L2-017 人以群分 Java题解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


原题:

社交网络中我们给每个人定义了一个“活跃度”,现希望根据这个指标把人群分为两大类,即外向型(outgoing,即活跃度高的)和内向型(introverted,即活跃度低的)。要求两类人群的规模尽可能接近,而他们的总活跃度差距尽可能拉开。

输入格式:

输入第一行给出一个正整数N(2≤N≤105)。随后一行给出N个正整数,分别是每个人的活跃度,其间以空格分隔。题目保证这些数字以及它们的和都不会超过231。

输出格式:

按下列格式输出:

Outgoing #: N1
Introverted #: N2
Diff = N3

其中N1是外向型人的个数;N2是内向型人的个数;N3是两群人总活跃度之差的绝对值。

输入样例1:

10
23 8 10 99 46 2333 46 1 666 555

输出样例1:

Outgoing #: 5
Introverted #: 5
Diff = 3611

输入样例2:

13
110 79 218 69 3721 100 29 135 2 6 13 5188 85

输出样例2:

Outgoing #: 7
Introverted #: 6
Diff = 9359

代码长度限制:16 KB        时间限制:150 ms        内存限制:64 MB

题目详情 - L2-017 人以群分 (pintia.cn)https://pintia.cn/problem-sets/994805046380707840/problems/994805061056577536


题解:

只需通过对数组进行排序,得到一个递增的数组,此时数组的前一半每个元素都小于该数组的后一半,不难发现,此时两边的差异达到最大。

通过C++代码运行较为容易,耗时短,内存占用少,但由于最近学习Java,所以尝试通过Java解答本题。C++代码对照在Java代码下方。

在初次运行时,使用Scanner输入流,导致测试样例全部超时,于是尝试用BufferedReader字符流输入,减少了50ms以上的耗时,但仍然有两个测试样例没能通过。

虽然超时,但是占用空间仍然没有达到系统限制,因此我尝试使用相较于Java提供的的sort(Dual-Pivot快排)以及parallelSort排序(并行排序-合并排序)而言(时间复杂度均为O(nlogn)),时间复杂度更低的桶排序(时间复杂度为O(n+m)),但就结果而言,由于Java语言特性,难以使用Java语言通过全部测试用例,使用桶排序会造成内存超出64MB的限制,因此最终还是使用Collections下的sort排序。


Java代码如下:

使用Collections下的sort方法,由于超时,代码未能通过全部测试点:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;public class Main {private final int Num;        //人数private final ArrayList<Integer> People = new ArrayList<>();   //存放每个人的性格private int count;      //性格总计public Main() throws IOException {BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));Num = Integer.parseInt(reader.readLine());String[] ss = reader.readLine().split(" ");for (int i = 0; i < Num; i++) {People.add(Integer.parseInt(ss[i]));count += People.get(i);}Collections.sort(People);}public static void main(String[] args) throws IOException {Main main = new Main();for (int i = 0; i < main.Num / 2; i++)main.count -= 2 * main.People.get(i);System.out.println("Outgoing #: " + (main.Num / 2 + main.Num % 2));System.out.println("Introverted #: " + main.Num / 2);System.out.println("Diff = " + main.count);}
}


C++代码如下:

可以看出,C++代码在运行时,占用内存更小,耗时更短。

#include <iostream>
#include <algorithm>
using namespace std;
int main()
{int num;int diff;cin >> num;int people[num];for (int i = 0; i < num; i++){cin >> people[i];diff += people[i];}sort(people, people + num);for (int i = 0; i < num / 2; i++)diff -= 2 * people[i];cout << "Outgoing #: " << (num + 1) / 2 << endl;cout << "Introverted #: " << num / 2 << endl;cout << "Diff = " << diff << endl;system("pause");return 0;
}


使用桶排序的Java代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;public class Main {private int Num;        //人数private ArrayList<Integer> People = new ArrayList<>();   //存放每个人的性格private int count;      //性格总计private int Max;    //数组最大值private int Min;    //数组最小值public Main() throws IOException {BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));Max = Integer.MIN_VALUE;Min = Integer.MAX_VALUE;count = 0;Num = Integer.parseInt(reader.readLine());String[] s = reader.readLine().split(" ");for (int i = 0; i < Num; i++) {People.add(Integer.parseInt(s[i]));Max = Math.max(Max, (Integer) People.get(i));Min = Math.min(Min, (Integer) People.get(i));count += (int) People.get(i);}
//        Collections.sort(People);}public static void main(String[] args) throws IOException {Main split = new Main();split.BucketSort();for (int i = 0; i < split.Num / 2; i++)split.count -= 2 * split.People.get(i);System.out.println("Outgoing #: " + (split.Num / 2 + split.Num % 2));System.out.println("Introverted #: " + split.Num / 2);System.out.println("Diff = " + split.count);}public void BucketSort() {
//       桶数int bucketNum = (Max - Min) / Num + 1;ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketNum);for (int i = 0; i < bucketNum; i++) {bucketArr.add(new ArrayList<>());}
//        置入桶中for (int i = 0; i < Num; i++) {int num = (People.get(i) - Min) / (Num);bucketArr.get(num).add(People.get(i));}
//        桶排序for (ArrayList<Integer> integers : bucketArr) {Collections.sort(integers);}
//        返回People.clear();for (ArrayList<Integer> integers : bucketArr) {People.addAll(integers);}}
}

分析:

Java程序编译后产生.class文件运行在JVM上,占用相当大的时间以及内存,在Windows上这种感知尤为明显。

关于桶排序:

详解:https://www.cnblogs.com/bigsaltfish/p/10067011.html

N:待排序长度         M:桶的数量

时间复杂度:O ( N + N * ( logN-logM ) )

空间复杂度:O ( N + M )

桶排序是一种牺牲空间换取时间的排序算法,当分配的桶的数量达到N时,时间复杂度最好,为O ( N  ),但空间复杂度上升,如果N较大,则会占用非常大的内存空间,如上方使用桶排序的Java代码,占用内存超出限制。

这篇关于L2-017 人以群分 Java题解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/247256

相关文章

SpringBoot简单整合ElasticSearch实践

《SpringBoot简单整合ElasticSearch实践》Elasticsearch支持结构化和非结构化数据检索,通过索引创建和倒排索引文档,提高搜索效率,它基于Lucene封装,分为索引库、类型... 目录一:ElasticSearch支持对结构化和非结构化的数据进行检索二:ES的核心概念Index:

Java方法重载与重写之同名方法的双面魔法(最新整理)

《Java方法重载与重写之同名方法的双面魔法(最新整理)》文章介绍了Java中的方法重载Overloading和方法重写Overriding的区别联系,方法重载是指在同一个类中,允许存在多个方法名相同... 目录Java方法重载与重写:同名方法的双面魔法方法重载(Overloading):同门师兄弟的不同绝

Spring配置扩展之JavaConfig的使用小结

《Spring配置扩展之JavaConfig的使用小结》JavaConfig是Spring框架中基于纯Java代码的配置方式,用于替代传统的XML配置,通过注解(如@Bean)定义Spring容器的组... 目录JavaConfig 的概念什么是JavaConfig?为什么使用 JavaConfig?Jav

Java数组动态扩容的实现示例

《Java数组动态扩容的实现示例》本文主要介绍了Java数组动态扩容的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1 问题2 方法3 结语1 问题实现动态的给数组添加元素效果,实现对数组扩容,原始数组使用静态分配

Java中ArrayList与顺序表示例详解

《Java中ArrayList与顺序表示例详解》顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构,:本文主要介绍Java中ArrayList与... 目录前言一、Java集合框架核心接口与分类ArrayList二、顺序表数据结构中的顺序表三、常用代码手动

JAVA项目swing转javafx语法规则以及示例代码

《JAVA项目swing转javafx语法规则以及示例代码》:本文主要介绍JAVA项目swing转javafx语法规则以及示例代码的相关资料,文中详细讲解了主类继承、窗口创建、布局管理、控件替换、... 目录最常用的“一行换一行”速查表(直接全局替换)实际转换示例(JFramejs → JavaFX)迁移建

Spring Boot Interceptor的原理、配置、顺序控制及与Filter的关键区别对比分析

《SpringBootInterceptor的原理、配置、顺序控制及与Filter的关键区别对比分析》本文主要介绍了SpringBoot中的拦截器(Interceptor)及其与过滤器(Filt... 目录前言一、核心功能二、拦截器的实现2.1 定义自定义拦截器2.2 注册拦截器三、多拦截器的执行顺序四、过

JAVA线程的周期及调度机制详解

《JAVA线程的周期及调度机制详解》Java线程的生命周期包括NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING和TERMINATED,线程调度依赖操作系统,采用抢占... 目录Java线程的生命周期线程状态转换示例代码JAVA线程调度机制优先级设置示例注意事项JAVA线程

JavaWeb项目创建、部署、连接数据库保姆级教程(tomcat)

《JavaWeb项目创建、部署、连接数据库保姆级教程(tomcat)》:本文主要介绍如何在IntelliJIDEA2020.1中创建和部署一个JavaWeb项目,包括创建项目、配置Tomcat服务... 目录简介:一、创建项目二、tomcat部署1、将tomcat解压在一个自己找得到路径2、在idea中添加

Java使用Spire.Doc for Java实现Word自动化插入图片

《Java使用Spire.DocforJava实现Word自动化插入图片》在日常工作中,Word文档是不可或缺的工具,而图片作为信息传达的重要载体,其在文档中的插入与布局显得尤为关键,下面我们就来... 目录1. Spire.Doc for Java库介绍与安装2. 使用特定的环绕方式插入图片3. 在指定位