`

山东大学09年复试机试题1

阅读更多
(题干为前辈回忆所得,并非原文,但已表达清楚)
    输入一个整数,它可以由n(n>=2)个连续整数相加得到,输出所有可能的连续整数序列,每个序列占一行,数字之间用空格分开,数据从小到大,每列按最小元素递增顺序排列,如果找不到,输出none
    例:21=1+2+3+4+5+6
       21=6+7+8
       21=10+11
    则输出 1 2 3 4 5 6
           6 7 8
           10 11

思路1:
    题目一拿到手,就觉得是和队列相关,因为是从1开始累加测试。队列初始时已经放入1,2(因为只有从3开始,才有1+2=3成立)。开始时先对队列元素总和进行计算:当小于要求值的时候把队尾元素值+1(也就是向后再取一个元素),将其入队,然后递归调用当前算法;当满足要求值的时候,把队列中的元素打印出来,并且将第一个元素出队,然后递归调用当前算法;当大于要求值的时候,将第一个元素出队,然后递归调用当前算法;当入队元素值=要求值/2+2时,return,因为此后的数据已经没有测试的意义。

具体程序如下:

递归版本
package test.shandong09;

import java.util.ArrayDeque;
import java.util.Iterator;

public class No1_1 {
	private ArrayDeque<Integer> arrayDeque;
	private int start;
	private int destination;
	private int times;
	
	public No1_1(int destination) {

		this.arrayDeque = new ArrayDeque<Integer>();
		this.start = 3;
		this.destination = destination;
		this.times=0;

		arrayDeque.offer(new Integer(1));
		arrayDeque.offer(new Integer(2));
	}

	public void getResult() {
		int temp = this.calculateSum(arrayDeque);
		if (start <= (destination / 2 + 2)) {
			if (temp < this.destination) {
				arrayDeque.offer(new Integer(this.start));
				this.start++;

			} else if (temp == this.destination) {
				System.out.println(arrayDeque.toString());
				arrayDeque.poll();
			} else if (temp > destination) {
				arrayDeque.poll();
			}
			this.getResult();
		} else {
			return;
		}
	}

	
	public int calculateSum(ArrayDeque<Integer> arrayDeque) {
		int result = 0;
		if (!arrayDeque.isEmpty()) {
			Iterator<Integer> iterator = arrayDeque.iterator();
			while (iterator.hasNext()) {
				Integer tempI = iterator.next();
				result += tempI.intValue();
			}
		}
		this.times++;
		return result;
	}

	public static void main(String[] args) {
		No1_1 no1_1 = new No1_1(500);//这里是要测试的数据
		no1_1.getResult();
		System.out.println("测试总次数为:" + no1_1.getTimes()+"\t测试截止数为(从3起始):"+no1_1.getStart());
	}
	
	public int getStart() {
		return start;
	}

	public int getTimes() {
		return times;
	}

}

输出为:
[8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]
[59, 60, 61, 62, 63, 64, 65, 66]
[98, 99, 100, 101, 102]
测试总次数为:501     测试截止数为(从3起始):253

最后输出的结果,数字之间是“,”隔开,这是不符合题目要求的,有待改进。

思路2
使用普通的循环累加计算法。即,开始值初始为1,截止值=目标值/2+2,累加值初始为0。从1开始累加,当发现累加值正好为目标值时,打印出当前序列(从当前的开始位到截止位,逐个+1然后打出),并将累加值清零后跳出此次循环;当累加值大于目标值时,将累加值清零后跳出此次循环。然后从开始值+1,再次进行……直到开始值=截止值结束运算。

具体程序如下:
循环版本:
package test.shandong09;

public class No1_2 {
	private long times;//测试(求和计算)总次数
	private int destination;//目标值
	
	public No1_2(int destination) {
		this.times = 0;
		this.destination = destination;
	}

	public boolean getResult() {
		boolean hasAnswer=false;//初始化hasAnswer变量
		int temp = destination / 2 + 2;//截止值
		int result = 0;//累加结果
		if (destination<=2){//传入的目标值必须>=3
			return false;
		}
		
		for (int i = 1; i <= temp; i++) {//外层循环,控制每轮累加的起始值
			for (int j = i; j <= temp; j++) {//内层循环,控制每轮累加的总值
				if (result == destination) {
					for (int k = i; k < j; k++) {//若找到目标序列,只需知道其起始值和终止值就行,然后累加得到每个元素
						System.out.print(k + " ");
						hasAnswer=true;
					}
					System.out.println();
					result = 0;
					break;
				} else if (result > destination) {//若大于目标值,则将累加结果清零,退出此轮叠加。
					result = 0;
					break;
				}
				result += j;//若前两种可能均不成立,则累加
				times++;//测试数+1
			}
		}
		return hasAnswer;
	}
	
	public long getTimes() {
		return times;
	}

	public static void main(String[] args) {
		No1_2 no1_2 = new No1_2(500);
		boolean b=no1_2.getResult();// 这里是要测试的数据
		if (b){
			System.out.println("测试总次数为:" + no1_2.getTimes());
		}else {
			System.out.println("none");
		}
	}
}


输出结果为:
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
59 60 61 62 63 64 65 66
98 99 100 101 102
测试总次数为:1768 测试截止数为(从1开始):252
分享到:
评论
2 楼 chinaemerson 2010-02-20  
      非常感谢你的关注,其实在测试的时候我也注意到了这一点(内存问题和效率问题),在学习程序设计的时候就知道要尽量避免使用递归。但考虑到这是考研的机试题,不会出的太大吧~呵呵。
      在发布第一个解法之后我又写了第二个解法,经测试,这个算法在时间效率和耐压性上比上一个算法有大幅提高。原因在于,我的第二个算法没有使用任何存储结构。我们都被自己的知识给套住了思维,都以为要有一个存储结构来储存现有的序列。其实错了,只要知道现有序列的起始值和终止值就可以使用for来迭代出序列来!因为都是连续的整数~~第二个程序在大数的压力下(如999999999),还是表现的不错的。但这种用for循环的方法,牺牲的是大量的处理器运算。当然,在存储器的访问时间面前,处理器运算所耗费的时间还是相当短的。

再次感谢你的关注!
1 楼 cxzucc 2010-02-20  
测试了下你的程序,在数字较大的时候会内存溢出,而且速度较慢,自己动手写了一个不用递归的,大家交流一下。
public class HHH {
public void find(int value) {
int i = value / 2;
List<Integer> list = new ArrayList<Integer>();
boolean result = false;
for (int j = 1; j <= i; j++) {
int sum = j, temp = j;
list.add(j);
while (sum < value) {
temp++;
sum += temp;
list.add(temp);
}
if (sum == value) {
result = true;
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
System.out.println();
}
list.clear();
}
if (!result)
System.out.println("none");
}

public static void main(String[] args) {
HHH hhh = new HHH();
hhh.find(111111);
}
}

相关推荐

    2019南京大学考研复试机试题.zip

    标题"2019南京大学考研复试机试题.zip"明确指出这是一个与2019年南京大学硕士研究生入学考试复试相关的资料压缩包。"机试题"通常指的是计算机科学或相关专业在复试阶段可能会遇到的上机编程题目,考生需要在规定时间...

    上海交通大学复试机试题详解

    上交复试机试题详解上交复试机试题详解 上交复试机试题详解上交复试机试题详解

    2003-2010年华中科技大学计算机考研复试机试题(含代码)

    1. 计算机考研复试机试题分析: 在华中科技大学计算机专业的考研复试中,机试题往往涵盖数据结构、算法、程序设计等方面的知识。考生需要对C/C++编程有深入的理解和实践经验,以及解决实际问题的能力。 2. C语言和...

    上海交通大学08年研究生复试机试题

    【标题】"上海交通大学08年研究生复试机试题"揭示了这是一份关于2008年上海交通大学计算机科学与技术专业研究生入学考试复试阶段的上机考试题目集。这样的试题通常涵盖计算机科学的核心概念、编程技能以及问题解决...

    山东大学计算机研究生考试复试试题

    【山东大学计算机研究生考试复试试题详解】 山东大学作为国内知名的高等学府,其计算机科学与技术专业的研究生考试历来备受关注。复试环节是决定考生能否顺利进入该校深造的重要一环,涵盖了笔试、上机和面试等多个...

    2010山东大学计算机复试上机题目

    根据给定的信息,我们可以推断出2010年山东大学计算机复试的上机考试题目及相关内容。虽然原文中的一些内容难以辨认,但通过已有的线索,我们仍可以总结出一些关键知识点。 ### 一、考试背景 - **考试名称**:2010...

    西北工业大学考研复试机试题及解答

    新中国成立以来,西工大一直是国家重点建设的高校,1960年被国务院确定为全国重点大学,“七五”、“八五”均被国务院列为重点建设的全国15所大学之一,是全国首批设立研究生院的22所高校之一,1995年首批进入“211...

    09年西北工业大学研究生复试机试题

    1. **奶牛飞盘队** - 这是一个典型的组合数学问题,涉及到求解模意义下的组合数。题目要求选出的奶牛排名之和为幸运数字F的倍数。这个问题可以通过动态规划或者容斥原理解决。首先计算出所有奶牛排名之和,然后找出...

    中南大学研究生复试机试题

    【中南大学研究生复试机试题】是一份针对中南大学计算机组成原理的研究生入学考试的复习资料,这个题目集合对于准备参加该校相关专业复试的学生来说是极具价值的资源。计算机组成原理是计算机科学与技术的基础课程,...

    南京理工大学 计算机专业考研 2023年复试上机试题真题.zip

    南京理工大学2023年计算机专业考研的复试上机试题真题是一份极其珍贵的复习资料,对于备考的考生来说,这份资源具有很高的参考价值。它涵盖了计算机领域的重要知识点,特别是与人工智能相关的部分,这对于想要在复试...

    东北大学复试试题收集

    "东北大学复试试题收集" 在软件工程部分,考题涵盖了接口与抽象类的区别、耦合的概念及分类、用例图等知识点。接口与抽象类的区别是面向对象编程的基本概念,两者都是为了实现多态性,但它们的实现方式不同。接口是...

    山东大学09计算机复试题目

    总而言之,山东大学计算机专业的复试是一个全面考察学生综合能力的环节,它不仅需要考生具备扎实的专业知识,更需要他们具备快速反应和高效处理问题的能力。因此,有志于进入山东大学深造的计算机学子,必须在平时的...

    2013-2018年中南大学复试机试题解

    2013年至2018年的中南大学复试机试题解是针对这一环节的重要参考资料,它涵盖了这六年间复试的编程题目及其解答,对于备考的学子来说具有极高的学习价值。 在这六年的试题中,我们可以发现一些重要的编程知识点: ...

    山东大学控制科学复试资料

    《山东大学控制科学复试资料详解》 控制科学与工程作为一门综合了自动化、电子信息、计算机等多领域知识的学科,其在山东大学的复试环节显得尤为重要。这份资料集全面覆盖了该专业复试的核心内容,旨在帮助考生充分...

    09年 山东大学,浙江大学 复试上机题目

    1. "09年山东大学计算机上级题目.doc":这个文档很可能包含了当年山东大学复试中的计算机上机部分的题目,可能涵盖了算法设计、数据结构、操作系统、网络、数据库等多个方面的编程问题。 2. "浙大2009复试上机.doc...

    2011年东南大学电气学院考研复试试题(回忆版)

    根据给定的信息,我们可以从这份2011年东南大学电气学院考研复试试题(回忆版)中提炼出几个关键的知识点。 ### 知识点一:电气工程基础理论 在第一题中,题目提到了关于电路分析的基础概念,如电路的基本组成、...

    2008年BUAA6系复试机试题.pdf

    - **定义**:素数(质数)是指在大于1的自然数中,除了1和它本身以外不再有其他因数的数。 - **判定方法**: - 试除法:对于一个待检验的数n,只需验证从2到√n之间的每个数是否能整除n即可。 - 埃拉托斯特尼筛法...

    中科大2006-2014年计算机复试机试题

    标题中的“中科大2006-2014年计算机复试机试题”指的是中国科学技术大学在2006年至2014年间用于计算机专业研究生复试阶段的上机考试题目。这些试题通常涵盖计算机科学与技术的基础知识,旨在评估考生的编程能力、...

    2010年西北工业大学机试考研复试试题(回忆版)

    综上所述,2010年西北工业大学机试考研复试试题主要围绕着计算机编程的基础知识进行考察,包括但不限于数据结构、算法设计、程序设计语言以及计算机基础知识等。通过对这些知识点的学习和掌握,可以帮助考生更好地...

Global site tag (gtag.js) - Google Analytics