最小生成元

来源:互联网 发布:mysql function 编辑:程序博客网 时间:2024/05/22 02:29

最小生成元

一、问题重述:

如果x加上x的各个位数字之和得到y,就说x是y的生成元;给出n,(1<=n<=100000),求最小生成元。无解输出0.例如,n=216,121,2005时的解分别为198,0,1979。

二、问题分析:

对于这个问题我看很多人的解法都是先枚举出100000以内的所有正整数m,计算m和m的各个位数字之和得到一个y的表,之后想知道哪个数字的最小生成元直接查表就行了;我个人认为这样做法对于大数据才会显得方便点。但是如果数据规模不是很大,这样计算100000次然后又进行查表操作显得麻烦太多。本文对此问题提出简单的解法:
思路:
枚举不一定从1开始,这是突破点,因为生成元x肯定比y小,而又要满足x加上x的各个位数字之和得到y,则此时,我们可以给x定下一个范围限度:
1.x<y
2.若x为y生成元,设y的位数length,x各个位数字之和为sum,那么就有x+sum=y,当sum取最大限度时,相应的x取得最小限度,而sum的限度就是length个9的和(sum    的最大限度还可以进行优化,考虑到那样会造成太多代码,所以取length个9)。从而得到:x>=y-9*length
由上分析得到枚举范围大大缩小;

三、源代码:

import java.util.Scanner;public class Main {public static void main(String[] args) {         Scanner cin = new Scanner(System.in);         while(cin.hasNext()){         Long n=cin.nextLong();         long temp=n-String.valueOf(n).length()*9;         int flag=0;         for(long i=temp;i<=n;i++){         if(f(i,n)){         flag++;         System.out.println(i);         break;         }         }         if(flag==0)         System.out.println("0");         }         cin.close();}private static boolean f(long i,Long n) {// TODO Auto-generated method stublong arg=i;while(arg>0){i+=arg%10;arg=arg/10;}if(i==n)return true;return false;}}

四、结论:

利用上述代码,即使现在要求一个几百为的大数(例如:位数为300位的数),最终求解次数也不过300*9=2700次而已。
原创粉丝点击