POJ 1338 解题报告

本文探讨了一种使用STL简化二分查找算法,并通过将数据类型从BigInteger转换为int来优化处理大整数的方法。通过维护三个指针进行齐头并进搜索,实现快速查找同时保持内存效率。

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

这道题我是自己写的二分查找加Java的BigInteger做的。看了后面打表的做法,大整数似乎是不需要的,int就足够了。

实际上二分查找维护一个排序的数组就是priority queue的主要作用,用STL可以大大简化过程。

基于以上两点,时间很慢。如果思路不变,但用STL+int,discuss上面有0ms的。

最聪明的做法应该是这样的:

http://poj.org/showmessage?message_id=113667

维护3个指针齐头并进,i2_mul指向可以乘2的最小的数(换句话说比这个数大的数就没必要试试乘2了)。其他两个变量同理。谁选上了(最小),谁更新下(++)。

thestoryofsnow1338Accepted6280K282MSJava2004B
import java.io.*;
import java.util.*;
import java.math.BigInteger;

public class Poj1338 {
	public static void main(String args[])
	{
		final int MAXN = 1500;

		final BigInteger TWO = BigInteger.valueOf(2);
		final BigInteger THREE = BigInteger.valueOf(3);
		final BigInteger FIVE = BigInteger.valueOf(5);

		final BigInteger[] BASE = new BigInteger[3];
		BASE[0] = TWO; BASE[1] = THREE; BASE[2] = FIVE;

		BigInteger[][] powers = new BigInteger[3][MAXN];
		
		for (int i = 0; i < 3; ++i)
		{
			powers[i][0] = BigInteger.ONE;
			for (int n = 1; n < MAXN; ++n)
			{
				powers[i][n] = powers[i][n - 1].multiply(BASE[i]);
				// if (n < 5)
				// {
				// 	System.out.println("powers[" + i + "][" + n + "]: " + powers[i][n]);
				// }
			}
		}

		BigInteger[] nums = new BigInteger[MAXN];
		int nnums = 0;
		int low, high, mid;
		for (int x = 0; x < MAXN; ++x)
		{
			for (int y = 0; (1 + x) * (1 + y) <= MAXN; ++y)
			{
				for (int z = 0; (1 + x) * (1 + y) * (1 + z) <= MAXN; ++z)
				{
					BigInteger num = powers[0][x].multiply(powers[1][y]).multiply(powers[2][z]);
					low = 0; high = nnums - 1;
					while (low <= high)
					{
						mid = low + (high - low) / 2;
						if (nums[mid].compareTo(num) <= 0)
						{
							low = mid + 1;
						}
						else
						{
							high = mid - 1;
						}
					}

					if (low == MAXN)
					{
						continue;
					}
					else
					{
						if (nnums < MAXN)
						{
							nnums++;
						}
						
						for (int i = nnums - 1; i >= low + 1; --i)
						{
							nums[i] = nums[i - 1];
						}
						nums[low] = num;
					}
				}
			}
		}

		// Collections.sort(nums);
		// for (int i = 0; i < 10; ++i)
		// {
		// 	System.out.print(nums[i] + " ");
		// }
		// System.out.println();


		Scanner cin = new Scanner(System.in);
		Integer n;

		while (cin.hasNext())
		{
			n = cin.nextInt();
			if (n == 0)
			{
				break;
			}
			System.out.println(nums[n - 1]);
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值