Java实现第九届蓝桥杯倍数问题
倍数问题
题目描述
【题目描述】
众所周知,小葱同学擅长计算,尤其擅长计算一个数是否是另外一个数的倍数。但小葱只擅长两个数的情况,当有很多个数之后就会比较苦恼。现在小葱给了你 n 个数,希望你从这 n 个数中找到三个数,使得这三个数的和是 K 的倍数,且这个和最大。数据保证一定有解。
【输入格式】
从标准输入读入数据。
第一行包括 2 个正整数 n, K。
第二行 n 个正整数,代表给定的 n 个数。
【输出格式】
输出到标准输出。
输出一行一个整数代表所求的和。
【样例输入】
4 3
1 2 3 4
【样例输出】
9
【样例解释】
选择2、3、4。
【数据约定】
对于 30% 的数据,n <= 100。
对于 60% 的数据,n <= 1000。
对于另外 20% 的数据,K <= 10。
对于 100% 的数据,1 <= n <= 10^5, 1 <= K <= 10^3,给定的 n 个数均不超过 10^8。
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
不要使用package语句。不要使用jdk1.7及以上版本的特性。
主类的名字必须是:Main,否则按无效代码处理。
PS:这里就是按照余数,将其分组,然后进行处理,O(NLogN)详细的看代码里面的注释,
有不对得地方或者不懂得地方欢迎评论
package 第二次模拟;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Stack;
public class 附加题 {
public static void main(String[] args) throws IOException {
//IO加入快
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String[] ss=br.readLine().trim().split(" ");
int n=Integer.parseInt(ss[0]);
int K=Integer.parseInt(ss[1]);
ss=br.readLine().trim().split(" ");
int[] a=new int[n];
for(int i=0;i<n;i++){
a[i]=Integer.parseInt(ss[i]);
}
//进行排序,当然这里如果可以自己写排序的话可能会更快一些
Arrays.sort(a);
int[] mod=Arrays.copyOf(a,n);
Stack<Integer>[] st=new Stack[K];
//数组初始化
init(st);
//我给这里%k是因为我要分为k个栈,因为我要保证三个数的和为k的倍数,这里%k为了分组,把相同余数的分到一起
//例子给的k=3 我要想办法把三个数变成3的倍数,大同小异,就是按照余数进行分组
//从小到大,进行插入,因为是栈,所以最大的在最上面,(后进去的在上面)
for(int i=0;i<n;i++){
mod[i]%=K;
st[mod[i]].add(a[i]);
}
int sum=0;
//如果能整除的数(余数为0)大于2个,那么我先把它变成sum,
if(st[0].size()>2){
Stack<Integer> temp=st[0];
sum=temp.pop()+temp.pop()+temp.pop();
}
int max=sum;
//这里因为要可以%k,那么三个数的和,可能为k,也可能为2k,当前是k的可能,下面是2k的可能
//i j p 就是我要取得三个余数 p+i+j==k(line:47) 所以我可以在这三个余数得数组里面选取最大的
for(int i=0;i<K;i++){
if(st[i].isEmpty())continue;
for(int j=i;j<K;j++){
if(st[j].isEmpty())continue;
int p=K-i-j;//这里保证了我的p+i+j的和为k
if(p>=0&&p<K){
if(st[p].isEmpty())continue;
//当我三个余数相等,就是这个栈得拿出来,然后我要栈顶得三个数
if(i==j&&j==p&&st[i].size()>=3){
Stack<Integer> temp=st[i];
sum=temp.pop()+temp.pop()+temp.pop();
//i和j一样时 取i得两个和p得一个栈顶得值,,下面同理
}else if(i==j&&j!=p&&st[i].size()>=2){
Stack<Integer> temp=st[i];
Stack<Integer> temp1=st[p];
sum=temp.pop()+temp.pop()+temp1.peek();
}else if(i==p&&i!=j&&st[i].size()>=2){
Stack<Integer> temp=st[i];
Stack<Integer> temp1=st[j];
sum=temp.pop()+temp.pop()+temp1.peek();
}else if(j==p&&i!=j&&st[j].size()>=2){
Stack<Integer> temp=st[j];
Stack<Integer> temp1=st[i];
sum=temp.pop()+temp.pop()+temp1.peek();
//当我三个都不相等得时候,我就可以把每个余数相对应得栈中得栈顶取出
}else if(i!=j&&j!=p){
Stack<Integer> temp=st[i];
Stack<Integer> temp1=st[j];
Stack<Integer> temp2=st[p];
sum=temp.peek()+temp1.peek()+temp2.peek();
}
if(sum>max)max=sum;
}
}
}
for(int i=0;i<K;i++){
if(st[i].isEmpty())continue;
for(int j=i;j<K;j++){
if(st[j].isEmpty())continue;
int p=2*K-i-j;
if(p>=0&&p<K){
if(st[p].isEmpty())continue;
if(i==j&&j==p&&st[i].size()>=3){
Stack<Integer> temp=st[i];
sum=temp.pop()+temp.pop()+temp.pop();
}else if(i==j&&j!=p&&st[i].size()>=2){
Stack<Integer> temp=st[i];
Stack<Integer> temp1=st[p];
sum=temp.pop()+temp.pop()+temp1.peek();
}else if(i==p&&i!=j&&st[i].size()>=2){
Stack<Integer> temp=st[i];
Stack<Integer> temp1=st[j];
sum=temp.pop()+temp.pop()+temp1.peek();
}else if(j==p&&i!=j&&st[j].size()>=2){
Stack<Integer> temp=st[j];
Stack<Integer> temp1=st[i];
sum=temp.pop()+temp.pop()+temp1.peek();
}else{
Stack<Integer> temp=st[i];
Stack<Integer> temp1=st[j];
Stack<Integer> temp2=st[p];
sum=temp.peek()+temp1.peek()+temp2.peek();
}
if(sum>max)max=sum;
}
}
}
System.out.println(max);
}
//进行数组初始化
private static void init(Stack<Integer>[] st) {
for(int i=0;i<st.length;i++){
st[i]=new Stack<Integer>();
}
}
}
PS:
这是一个必炸的方法,当时天真的认为dfs,结果。。。还是附上把,下次给自己一个提醒
import java.util.Scanner;
public class MultiplyMax {
static int max = 0;
//深搜递归调用
//解释:sum代表当前找到的数的总和,
//k题目所给,cur代表当前遍历到的数组下标,
//curCount代表当前已经找到的最大数个数
static void dfs(int[] a,int sum,int k,int cur,int curCount) {
//满足题目要求
if( sum%k == 0 && curCount == 3 && max<sum ) {
max = sum;
}
//当前遍历已经到达数组尾部
if( cur == a.length ) return ;
//添加当前a[cur]元素,成为三个数中一个
dfs(a,sum+a[cur],k,cur+1,curCount+1);
//不添加当前a[cur]元素
dfs(a,sum,k,cur+1,curCount);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
int[] a = new int[n];
for( int i=0; i<n; i++ ) {
a[i] = sc.nextInt();
}
//初始情况从数组下标0开始遍历
dfs(a,0,k,0,0);
System.out.println(max);
}
}
Java实现第九届蓝桥杯倍数问题的更多相关文章
- Java实现第九届蓝桥杯全球变暖
全球变暖 题目描述 你有一张某海域NxN像素的照片,"."表示海洋."#"表示陆地,如下所示: ....... .##.... .##.... ....##. ...
- Java实现第九届蓝桥杯小朋友崇拜圈
小朋友崇拜圈 题目描述 班里N个小朋友,每个人都有自己最崇拜的一个小朋友(也可以是自己). 在一个游戏中,需要小朋友坐一个圈, 每个小朋友都有自己最崇拜的小朋友在他的右手边. 求满足条件的圈最大多少人 ...
- Java实现第九届蓝桥杯字母阵列
字母阵列 题目描述 仔细寻找,会发现:在下面的8x8的方阵中,隐藏着字母序列:"LANQIAO". SLANQIAO ZOEXCCGB MOAYWKHI BCCIPLJQ SLAN ...
- Java实现第九届蓝桥杯耐摔指数
耐摔指数 题目描述 x星球的居民脾气不太好,但好在他们生气的时候唯一的异常举动是:摔手机. 各大厂商也就纷纷推出各种耐摔型手机.x星球的质监局规定了手机必须经过耐摔测试,并且评定出一个耐摔指数来,之后 ...
- Java实现第九届蓝桥杯三体攻击
三体攻击 [题目描述] 三体人将对地球发起攻击.为了抵御攻击,地球人派出了 A × B × C 艘战舰,在太空中排成一个 A 层 B 行 C 列的立方体.其中,第 i 层第 j 行第 k 列的战舰(记 ...
- Java实现第九届蓝桥杯堆的计数
堆的计数 题目描述 我们知道包含N个元素的堆可以看成是一棵包含N个节点的完全二叉树. 每个节点有一个权值.对于小根堆来说,父节点的权值一定小于其子节点的权值. 假设N个节点的权值分别是1~N,你能求出 ...
- Java实现第九届蓝桥杯阶乘位数
阶乘位数 题目描述 小明维护着一个程序员论坛.现在他收集了一份"点赞"日志,日志共有N行.其中每一行的格式是: ts id 表示在ts时刻编号id的帖子收到一个"赞&qu ...
- Java实现第九届蓝桥杯螺旋折线
螺旋折线 题目描述 如图p1.pgn所示的螺旋折线经过平面上所有整点恰好一次. 对于整点(X, Y),我们定义它到原点的距离dis(X, Y)是从原点到(X, Y)的螺旋折线段的长度. 例如dis(0 ...
- Java实现第九届蓝桥杯递增三元组
题目6.递增三元组 题目描述 给定三个整数数组 A = [A1, A2, - AN], B = [B1, B2, - BN], C = [C1, C2, - CN], 请你统计有多少个三元组(i, j ...
随机推荐
- mysql查询日期分组,不存在的补全0,做每天数据图表,根据日期,N天数往前查
SELECT IFNULL( DATA.count, 0 ) AS count, day_list.DAY AS createTime FROM ( SELECT DATE_FORMAT( creat ...
- 黑马程序员_毕向东_Java基础视频教程——常量(随笔)
常量 常量表示不能被改变的数值. Java常量的分类 整型常量.所有整数 小数常量.所有小数 布尔型常量.特殊只有两个值:true.false. 字符常量.将一个数字字母或者符号用单引号(' ')标识 ...
- scikit-learn 梯度提升树(GBDT)调参笔记
在梯度提升树(GBDT)原理小结中,我们对GBDT的原理做了总结,本文我们就从scikit-learn里GBDT的类库使用方法作一个总结,主要会关注调参中的一些要点. 1. scikit-learn ...
- County Fair Events
先按照结束时间进行排序,取第一个节日的结束时间作为当前时间,然后从第二个节日开始搜索,如果下一个节日的开始时间大于当前的时间,那么就参加这个节日,并更新当前时间 #include <bits/s ...
- 如何在本地调试你的 Spark Job
生产环境的 Spark Job 都是跑在集群上的,毕竟 Spark 为大数据而生,海量的数据处理必须依靠集群.但是在开发Spark的的时候,不可避免我们要在本地进行一些开发和测试工作,所以如何在本地用 ...
- redis python操作
1.基于连接池方式实现对五个数据类型操作,每种数据类型2个操作 2.基于spring-data-redis 基于jedis来实现对五种数据类型操作,每种数据类型实现两个操作,包括事务 以上为基于jav ...
- Objective-C中的加号与减号
在Objective-C中,方法分为类方法和实例方法. 前置加号(+)的方法为类方法,这类方法是可以直接用类名来调用的,它的作用主要是创建一个实例.有人把它称为创建实例的工厂方法. 前置减号(-)的方 ...
- Jenkins-Sonar集成配置及注意点
首先说说关于Jenkins集成Sonar的相关配置:我jenkins与Sonar不在同一个服务器上! 先现在 SonarQube Scanner 插件. SonarQube Servers:系统配置 ...
- Django中的事务与ajax
一 事务与锁 1.行级锁 行级锁是由存储引擎实现的.如mysql里默认指定的InnoDB存储引擎,由它实现行级锁.InnoDB的行级锁定同样分为两种类型,共享锁(X)和排他锁(S). 对于UPDATE ...
- ios审核 "prefs:root="被拒
https://blog.csdn.net/xnickname666/article/details/83068516 使用TZImagePicker https://github.com/banc ...