OJ-2:区间问题【九度1554】
- 题目描述:
-
给定一个数组,判断数组内是否存在一个连续区间,使其和恰好等于给定整数k。
- 输入:
-
输入包含多组测试用例,每组测试用例由一个整数n(1<=n<=10000)开头,代表数组的大小。
接下去一行为n个整数,描述这个数组,整数绝对值不大于100。
最后一行为一个整数k(大小在int范围内)。
- 输出:
-
对于每组测试用例,若存在这个连续区间,输出其开始和结束的位置,s,e(s <= e)。
若存在多个符合条件的输出,则输出s较小的那个,若仍然存在多个,输出e较小的那个。
若不存在,直接输出"No"。
- 样例输入:
-
5
-1 2 3 -4 9
5
3
-1 2 -3
7
2
-1 1
0
- 样例输出:
-
2 3
No
1 2
package jobdu.wangdao; import java.util.Scanner; /**
* 题目描述: 给定一个数组,判断数组内是否存在一个连续区间,使其和恰好等于给定整数k。
*
*/
public class Question1554 { private static void solve(int[] array, int k) {
boolean find = false;
for (int i = 0; i < array.length; i++) {
if (!find) {
int sum = 0;
for (int j = i; j < array.length; j++) {
sum += array[j];
if (sum == k) {
find = true;
System.out.println((i + 1) + " " + (j + 1));
break;
}
}
}
}
if (!find)
System.out.println("No");
} public static void main(String[] args) { @SuppressWarnings("resource")
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
int n = scanner.nextInt();
int[] array = new int[n];
for (int i = 0; i < n; i++) {
array[i] = scanner.nextInt();
}
int k = scanner.nextInt();
solve(array, k);
}
}
}
这个解答用的是暴力o(n*n)破解,提交后九道提示超时。
用动态规划的思想,记录从a[0]开始到a[i]的和存入sum[i],那么当sum[i]-sum[j]=k的时候从a[j+1]到a[i]的和就为k。
package jobdu.wangdao; import java.io.IOException;
import java.io.StreamTokenizer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map; /**
* 题目描述: 给定一个数组,判断数组内是否存在一个连续区间,使其和恰好等于给定整数k。
*
*/
public class Question1554 { /**
* 暴力求和比较
*
* @param array
* @param k
* @return
*/
public static Section solve(int[] array, int k) {
boolean find = false;
for (int i = 0; i < array.length; i++) {
if (!find) {
int sum = 0;
for (int j = i; j < array.length; j++) {
sum += array[j];
if (sum == k) {
find = true;
System.out.println((i + 1) + " " + (j + 1));
return new Section(i + 1, j + 1);
}
}
}
}
if (!find)
System.out.println("No");
return null;
} public static Section solve2(int[] array, int k) {
int[] sumList = new int[array.length];// 先计算出前0-i个数的和存入sumList
Map<Integer, List<Integer>> map = new HashMap<Integer, List<Integer>>();
// 记录前i个数的和和值相同的下标
int sum = 0;
for (int i = 0; i < array.length; i++) {
sum = sum + array[i];
sumList[i] = sum;
if (map.containsKey(sum)) {// 将和的下标存入map
List<Integer> indexList = map.get(sum);
indexList.add(i);
} else {
List<Integer> indexList = new ArrayList<Integer>();
indexList.add(i);
map.put(sum, indexList);
}
} boolean find = false;
List<Section> list = new ArrayList<Section>();
for (int j = 0; j < sumList.length; j++) {
int sumi = sumList[j];// 当前遍历的前j个数的和为sumi
if (sumi == k) {// 如果前j个数的和就是k,那么直接为一组解
Section node = new Section(1, (j + 1));
list.add(node);// 加入解集合
find = true;
continue;
}
int temp = sumi + k;// 计算出对应的和已保证a[i]-a[j]=k
if (map.containsKey(temp) && map.get(temp).size() > 0) {
// 如果存在a[i]-a[j]=k,那么从第j+1个数到第i个数之和就为k,这里下标从0开始
int start = j + 2;
int end = -1;
for (Integer integer : map.get(temp)) {// 从和相同的下标中选离j最近比i大的下标作为最后的解
if (integer >= j) {
end = integer + 1;
break;
}
}
if (end >= 0) {
list.add(new Section(start, end));
find = true;
}
}
} if (!find)
System.out.println("No");
else {
Collections.sort(list);// 对可能的解做一次排序,找到符合题意的解
Section section = list.get(0);
System.out.println(section.start + " " + section.end);
return section;
}
return null;
} /**
* 确保List的排序
*
*/
public static class Section implements Comparable<Section> {
int start, end; public Section(int start, int end) {
this.start = start;
this.end = end;
} @Override
public int compareTo(Section o) {
if (this.start == o.start)
return this.end - o.end;
return this.start - o.start;
} } public static void main(String[] args) throws IOException { @SuppressWarnings("deprecation")
StreamTokenizer st = new StreamTokenizer(System.in);
while (st.nextToken() != StreamTokenizer.TT_EOF) {
int n = (int) st.nval;
int[] array = new int[n];
for (int i = 0; i < n; i++) {
st.nextToken();
array[i] = (int) st.nval;
}
st.nextToken();
int k = (int) st.nval;
solve2(array, k);
}
}
}
其中一开始使用Scanner的方法作为输入,优化许久还是超时,查看其它成功代码采用的是StreamTokenizer方式作为输入。也改为StreamTokenizer方式后,提交通过。
OJ-2:区间问题【九度1554】的更多相关文章
- 【九度OJ】题目1065:输出梯形 解题报告
[九度OJ]题目1065:输出梯形 解题报告 标签(空格分隔): 九度OJ [LeetCode] http://ac.jobdu.com/problem.php?pid=1065 题目描述: 每组测试 ...
- 【九度OJ】题目1431:Sort 解题报告
[九度OJ]题目1431:Sort 解题报告 标签(空格分隔): 九度OJ [LeetCode] http://ac.jobdu.com/problem.php?pid=1431 题目描述: 给你n个 ...
- 九度oj 题目1087:约数的个数
题目链接:http://ac.jobdu.com/problem.php?pid=1087 题目描述: 输入n个整数,依次输出每个数的约数的个数 输入: 输入的第一行为N,即数组的个数(N<=1 ...
- 九度OJ 1502 最大值最小化(JAVA)
题目1502:最大值最小化(二分答案) 九度OJ Java import java.util.Scanner; public class Main { public static int max(in ...
- 九度OJ,题目1089:数字反转
题目描述: 12翻一下是21,34翻一下是43,12+34是46,46翻一下是64,现在又任意两个正整数,问他们两个数反转的和是否等于两个数的和的反转. 输入: 第一行一个正整数表示测试数据的个数n. ...
- 九度OJ 1500 出操队形 -- 动态规划(最长上升子序列)
题目地址:http://ac.jobdu.com/problem.php?pid=1500 题目描述: 在读高中的时候,每天早上学校都要组织全校的师生进行跑步来锻炼身体,每当出操令吹响时,大家就开始往 ...
- 九度OJ 1531 货币面值(网易游戏2013年校园招聘笔试题) -- 动态规划
题目地址:http://ac.jobdu.com/problem.php?pid=1531 题目描述: 小虎是游戏中的一个国王,在他管理的国家中发行了很多不同面额的纸币,用这些纸币进行任意的组合可以在 ...
- 九度OJ 1024 畅通工程 -- 并查集、贪心算法(最小生成树)
题目地址:http://ac.jobdu.com/problem.php?pid=1024 题目描述: 省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但 ...
- 九度OJ 1371 最小的K个数 -- 堆排序
题目地址:http://ac.jobdu.com/problem.php?pid=1371 题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4 ...
随机推荐
- Open CV leaning
刚接触Open CV 几个比较好的介绍: OpenCV学习笔记:https://blog.csdn.net/yang_xian521/column/info/opencv-manual/3 OpenC ...
- 【题解】[ZJOI2009]假期的宿舍
\(\color{red}{Link}\) \(\text{Solution:}\) 把人和床看成点,问题转化为二分图. 于是,对于每一个在校生,我们建立出他的床点:然后对于每一个在校生,他们自己可以 ...
- MySQL的简单实用 手把手教学
------------恢复内容开始------------ MySQL的使用 1.登陆数据库 打开terminal 在终端根文件目录下输入/usr/local/mysql/bin/mysql -u ...
- 如何win7安装tomcat
首先安装jdk,查看当前jdk版本. >java -version 显示的是1.8.0_131 为此我们安装的tomcat版本是apache-tomcat-9.0.38-windows-x64. ...
- 原生tab选项卡
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 实验报告系列:实验一 HTML语言的简单网页制作
实验一 HTML语言的简单网页制作 一.实验目的: 1.掌握常用的HTML语言标记: 2.利用文本编辑器建立HTML文档,制作简单网页. 3.学习将其它格式的文档转换成HTML格式的文档 二.实验内容 ...
- keccak和sha3的区别
keccak应用 在以太坊中,用keccak哈希算法来计算公钥的256位哈希,再截取这256位哈希的后160位哈希作为地址值. keccak和sha3的区别 sha3由keccak标准化而来,在很多场 ...
- pytest文档40-pytest.ini配置用例查找规则(面试题)
前言 面试题:pytest如何执行不是test开头的用例?如执行 xxx_*.py这种文件的用例. pytest.ini 配置文件可以修改用例的匹配规则. pytest命令行参数 cmd打开输入pyt ...
- go 正则 爬取邮箱代码
package main import ( "net/http" "fmt" "io/ioutil" "regexp" ...
- linux(centos8):用grep命令查找文件内容
一,grep的用途: linux平台有最常用的三大文本处理工具:awk/sed/grep grep的功能:搜索指定文件的内容,按照指定的模式匹配,并输出匹配内容所在的行. 需要注意的地方:grep只支 ...