HDU ACM 1005 java版

本文分享了一次尝试解决模运算导致的超时问题,并通过优化代码提高了程序运行效率的经历。作者从简单直接的实现出发,意识到需要利用周期性原理来优化算法。最终通过引入模运算的周期性概念,实现了在限制时间内正确且高效地计算序列值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   原题链接: http://acm.hdu.edu.cn/showproblem.php?pid=1005

Problem Description
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).
 

Input
The input consists of multiple test cases. Each test case contains 3 integers A, B and n on a single line (1 <= A, B <= 1000, 1 <= n <= 100,000,000). Three zeros signal the end of input and this test case is not to be processed.
 

Output
For each test case, print the value of f(n) on a single line.
 

Sample Input
   
   
1 1 3 1 2 10 0 0 0
 

Sample Output
   
   
2 5

很早前就注册过大名鼎鼎的杭电acm的账号,但是一直没有提交过代码。昨天在论坛上看到有人求java版本的1005代码,所以就试着写了一下:
首先,看题目,貌似很简单的一个问题,直接代入公式就行了,觉得有些不可思议,但是还是写了最初版本的代码,如下:
package algorithms;

import java.math.BigInteger;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int a, b;
        int n;
        while (in.hasNext()) {
            a = in.nextInt();
            b = in.nextInt();
            n = in.nextInt();
            // 1 <= A, B <= 1000, 1 <= n <= 100,000,000
            if (a < 1 & a > 1000 & b < 1 & b > 1000 & b < 1 & a > 100000000)
                System.exit(0);
            if (a == 0 & b == 0 & n == 0)
                System.exit(0);
            int count = n - 2;
            int i = 0;
            
            BigInteger f[] = new BigInteger[2];
            f[0] = BigInteger.valueOf(1);
            f[1] = BigInteger.valueOf(1);
            while (i < count) {
                BigInteger tmp = (f[0].multiply(BigInteger.valueOf(a)).add(f[1]
                        .multiply(BigInteger.valueOf(b)))).remainder(BigInteger
                        .valueOf(7));
                f[1] = f[0];
                f[0] = tmp;
                i++;
            }
            System.out.println(f[0]);
        }
        in.close();
    }

}
在本地测试了Sample中的几组数据,结果皆没有问题,然后就去提交code,结果没有期望的ac,而是 Time Limit Exceeded,这时候才意识到这个问题不是考察能不能得出结果,而是考察代码的效率。
想要提高运行时间,自然要优化代码,但是在最初版本的代码上,试着优化了几次,皆是超时,这时候从网上查了下思路,才意识到没有注意到mod运算导致的问题。
因为f(n)的结果是模7的,那么f(n)的结果只可能在{0,1,2,3,4,5,6,}中,这样f(n)与f(n-1)的结果只可能是7*7 = 49种,合理利用周期性,便可以大大提高程序运行时间。
最终AC的代码如下,Rank 280,我不是搞算法的,懒得再优化了:
import java.util.Scanner;

public class Main{
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int a, b;
		int n;
		while (in.hasNext()) {
			a = in.nextInt();
			b = in.nextInt();
			n = in.nextInt();
			// 1 <= A, B <= 1000, 1 <= n <= 100,000,000
			if (a < 1 & a > 1000 & b < 1 & b > 1000 & b < 1 & a > 100000000)
				System.exit(0);
			if (a == 0 & b == 0 & n == 0)
				System.exit(0);
			int f[] = new int[50];
			for (int i = 1; i < 50; i++) {
				if (i == 1 || i == 2) {
					f[i] = 1;
				} else {
					f[i] = (a * f[i - 1] + b * f[i - 2]) % 7;
				}
			}
			System.out.println(f[n % 49]);
		}
		in.close();
	}

}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值