<MEMORY>Project Euler NO55

寻找Lychrel数
本文探讨了Lychrel数的概念及如何通过编程方法确定10000以下的Lychrel数数量。Lychrel数是指无法通过反复反转并相加的方式形成回文数的整数。文章提供了一个具体的Java实现示例。

我们将47与它的逆转相加,47 + 74 = 121, 可以得到一个回文。

并不是所有数都能这么快产生回文,例如:

349 + 943 = 1292,
1292 + 2921 = 4213
4213 + 3124 = 7337

也就是说349需要三次迭代才能产生一个回文。

虽然还没有被证明,人们认为一些数字永远不会产生回文,例如196。那些永远不能通过上面的方法(逆转然后相加)产生回文的数字叫做Lychrel数。因为这些数字的理论本质,同时也为了这道题,我们认为一个数如果不能被证明的不是Lychrel数的话,那么它就是Lychre数。此外,对于每个一万以下的数字,你还有以下已知条件:这个数如果不能在50次迭代以内得到一个回文,那么就算用尽现有的所有运算能力也永远不会得到。10677是第一个需要50次以上迭代得到回文的数,它可以通过53次迭代得到一个28位的回文:4668731596684224866951378664。

令人惊奇的是,有一些回文数本身也是Lychrel数,第一个例子是4994。

10000以下一共有多少个Lychrel数?


import java.util.ArrayList;
import java.util.List;


public class Problem55
{
	public static void main(String[] args)
	{
		long start = System.currentTimeMillis();
		System.out.print("answer:  ");
		
		howmany();
		
		long end = System.currentTimeMillis();
		System.out.print("time:  ");
		System.out.println(end - start);
	}
	
	static void howmany()
	{
		int nu = 0;
		for (int i = 1; i < 10000; i++)
		{
			boolean ispo = false;
			int t = i;
			List<Integer> temp = new ArrayList<>();//用list,大数据
			while(t != 0)
			{
				temp.add(t % 10);
				t /=10;
			}
			for (int j = 1; j <=50; j++)
			{
				temp = add(temp);
				
				if (temp.size() == 0)
				{
					ispo = true;
					break;
				}
			}
			
			if (!ispo)
			{
				nu ++;
//				System.out.println(i);
			}
		}
		
		System.out.println(nu);
	}
	
	static List<Integer> add(List<Integer> array)
	{
		List<Integer> arr = new ArrayList<>();
		int len = array.size();
		int temp = 0;
		for (int i = 0; i < len; i++)
		{
			temp = array.get(i) + array.get(len - 1 - i) + temp;
			arr.add(temp % 10);
			temp /= 10;
		}
		if (temp != 0)			//相加,不会出现temp为2位数;所以直接加
		{
			arr.add(temp);
		}
		List<Integer> arr0 = new ArrayList<>();
		for (int i = 0; i < len; i++)
		{
			if (arr.get(i) != arr.get(arr.size() - 1 - i))
			{
				//前后交换下
				for (int j = arr.size() - 1; j >= 0; j--)
				{
					arr0.add(arr.get(j));
				}
				
				return arr0;
			}
		}
		//返回 size 为0;说明是回文
		return arr0;
	}
}


answer:  249
time:  86


Single_External_Matrix Camera::Camera2OpenCVCamera(const cv::Vec3f& _euler_angles, cv::Mat& _translation_vector) { Single_External_Matrix opencvcamera; cv::Mat RT_camera2vehicle = getExternalMatrix(_euler_angles, _translation_vector); cv::Mat RT_vehicle2camera = RT_camera2vehicle.inv(); // 提取最后一列的前三个元素 cv::Mat lastColumn = RT_vehicle2camera.col(3); cv::Mat lastColumnTopThree = lastColumn.rowRange(0, 3); cv::Mat R_opencvcamera2camera = (cv::Mat_<double>(3, 3) << 0, -1, 0, 0, 0, -1, 1, 0, 0); opencvcamera.translation_vector = R_opencvcamera2camera * lastColumnTopThree; cv::Mat R_camera2vehicle; RT_camera2vehicle(cv::Rect(0, 0, 3, 3)).copyTo(R_camera2vehicle); //这里是前左上变换右下前 cv::Mat R_opencvcamera2vehicle = R_camera2vehicle * R_opencvcamera2camera.inv(); opencvcamera.euler_angles = Matrix2Euler(R_opencvcamera2vehicle.inv()); return opencvcamera; } cv::Mat Camera::getExternalMatrix(const cv::Vec3d& _angle, const cv::Mat& _tvec) { cv::Mat T; T = Euler2Matrix(_angle); T.at<double>(0, 3) = _tvec.at<double>(0, 0); T.at<double>(1, 3) = _tvec.at<double>(1, 0); T.at<double>(2, 3) = _tvec.at<double>(2, 0); return T; } // Calculates rotation matrix to euler angles. cv::Mat Camera::Euler2Matrix(const cv::Vec3d& _angle) { // Calculate rotation about x axis cv::Mat R_x = (cv::Mat_<double>(4, 4) << 1, 0, 0, 0, 0, cos(_angle[0]), -sin(_angle[0]), 0, 0, sin(_angle[0]), cos(_angle[0]), 0, 0, 0, 0, 1); // Calculate rotation about y axis cv::Mat R_y = (cv::Mat_<double>(4, 4) << cos(_angle[1]), 0, sin(_angle[1]), 0, 0, 1, 0, 0, -sin(_angle[1]), 0, cos(_angle[1]), 0, 0, 0, 0, 1); // Calculate rotation about z axis cv::Mat R_z = (cv::Mat_<double>(4, 4) << cos(_angle[2]), -sin(_angle[2]), 0, 0, sin(_angle[2]), cos(_angle[2]), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); // Combined rotation matrix cv::Mat R = R_z * R_y * R_x; return R; } // Calculates rotation matrix to euler angles cv::Vec3d Camera::Matrix2Euler(const cv::Mat& _rotation) { #if defined(WIN32) || defined(LINUX) assert(isRotationMatrix(_rotation)); #endif double sy = sqrt(_rotation.at<double>(0, 0) * _rotation.at<double>(0, 0) + _rotation.at<double>(1, 0) * _rotation.at<double>(1, 0)); bool singular = sy < 1e-6; // If double x, y, z; if (!singular) { x = atan2(_rotation.at<double>(2, 1), _rotation.at<double>(2, 2)); y = atan2(-_rotation.at<double>(2, 0), sy); z = atan2(_rotation.at<double>(1, 0), _rotation.at<double>(0, 0)); } else { x = atan2(-_rotation.at<double>(1, 2), _rotation.at<double>(1, 1)); y = atan2(-_rotation.at<double>(2, 0), sy); z = 0; } return cv::Vec3d(x, y, z); }
最新发布
09-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值