论坛首页 Java企业应用论坛

(ACM系列之一)从简单开始

浏览 6886 次
该帖已经被评为隐藏帖
作者 正文
   发表时间:2011-04-05   最后修改:2011-04-05
本人冒着被投新手帖或隐藏帖的危险,预备在本论坛持续发布一个ACM算法题Java版的帖子。

我只有一个简单的目的,让“爱思考、爱编程”成为一种习惯。

当然不能只有代码的堆砌。很多大师和专家在研究设计模式、算法和很多Java的基础,关于面向对象、性能、并发和各种开源项目的帖子层出不穷,小弟也在此论坛受益菲浅。本着“你快乐,我快乐,大家快乐”的原则,小弟的帖子开始出现了。若有不当,可投新手或隐藏,论坛积分已是浮云,“失去的一定能找回来”。

做一件事情当然需要从简单的开始,循序渐进。所谓“欲速则不达,贪多嚼不烂”啊!!

此贴是第一帖,下面进入正题:

题目是这样的:
A number sequence is defined as follows:

f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.

Given A, B, and n, you are to calculate the value of f(n).


这几个简单的单词我就不翻译了。我主要说说我的解法。

对于这个题,我相信给许许多多的程序员的第一印象就是递归。递归是一个伟大的发明,是一种美丽的思想。生活中处处有递归。

不过在java中,递归也有危险。对海量数据而言,递归会造成java对内存溢出,我刚学编程那会儿,可是遇到过不少。

对于这道题而言,是需要先分析的。这是一道简单的概率题(我知道,我知道,新手帖嘛。。)

仔细观察,就会发现,这道题的规律,当然是除了递归性质之后的规律。

首先,f(1) = 1,f(2) = 1。这个是前提,在代码中体现在if判断中。

最重要的是第三个式子,f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7。(mod翻译成java语言为%)

首先,我们会发现f(n)的取值范围为0-6,且未等概率的。同样f(n-1)与f(n-2)的取值范围也为0-6,同样为等概率的。

其次,我们可以认为f(n)是由f(n-1)与f(n-2)组合而成的,A和B是常量,f(n-1)与f(n-2)的取值范围确定,且为等概率事件,那么就有7*7=49种结果。那么我的思想就是重复计算(我知道这不是最好的算法,这也是我发帖来讨论的原因),还是利用递归思想,循环计算M次,而M = n % 49。即去总次数去掉重复结果计算后的次数。

在代码中,我用left代替了A * f(n - 1),用right代替了B * f(n - 2)。

现在,就可以上代码了。
package org.fantasizer.algorithms.acm.p1005;

public class Main {
	public static void main(String[] args) {
		System.out.println(calculate(1, 1, 3));
		System.out.println(calculate(1, 2, 10));
		System.out.println(calculate(1, 2, 100000000));
	}

	public static long calculate(int A, int B, int n) {
		if (n == 1 || n == 2) {
			return 1;
		}

		long left = 1;
		long right = 1;

		long result = 0;
		for (int i = 2; i < n % 49; i++) {
			result = (A * left + B * right) % 7;
			right = left;
			left = result;
		}
		return result;
	}
}



最后说一下,讨论是用来学习的一种很好的方式。
   发表时间:2011-04-05  
习惯占个位置以编辑后文。
0 请登录后投票
   发表时间:2011-04-05  
你分少,就不投你新手了。不过暂时对这个没什么兴趣。先占位.
0 请登录后投票
   发表时间:2011-04-05  
peterwei 写道
你分少,就不投你新手了。不过暂时对这个没什么兴趣。先占位.


你的意思是说真的值得投新手么?如果是这样,后续的就不发了。
0 请登录后投票
   发表时间:2011-04-05  
。。。囧了
打击LZ自信心了
0 请登录后投票
   发表时间:2011-04-05  
quxiaoyong 写道
peterwei 写道
你分少,就不投你新手了。不过暂时对这个没什么兴趣。先占位.


你的意思是说真的值得投新手么?如果是这样,后续的就不发了。

不值得,好好努力。哈哈。现在发贴的人比较少。
0 请登录后投票
   发表时间:2011-04-05  
珠海的……BNUZ?

在JE中贴算法的帖子,很难引起关注的。去各大OJ站的讨论版玩吧。
0 请登录后投票
   发表时间:2011-04-05  
  没想通的是为什么计算M次就行了,另外49次计算所得一定为0吗?楼主能详细解释否,或者给点思路也行。
0 请登录后投票
   发表时间:2011-04-05   最后修改:2011-04-06
这是一个改进的斐波那契序列%49这块应该还可以再改进一下
0 请登录后投票
   发表时间:2011-04-05  
其实还好的啊。支持下
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics