山东大学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

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

具体程序如下:

[b]递归版本[/b]

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;
}

}

输出为:
[table]
|[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|
[/table]
最后输出的结果,数字之间是“,”隔开,这是不符合题目要求的,有待改进。

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

具体程序如下:
[b]循环版本:[/b]

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");
}
}
}


输出结果为:
[table]
|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|
[/table]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值