A尾相等数

题目描述:

从键盘输入一个int数A(A > 1),如果存在int数X和Y(X>Y),使得A^X和A^Y均大于1000,且他们的末尾三位数相等,则称X和Y是一对“A尾相等数”

求:
任意输入A,使得X+Y值最小的A尾相等数。

如:
A = 2  ---》  X+Y = 120

分析:

 

代码:

 1using System;
 2using System.Collections.Generic;
 3using System.Text;
 4
 5namespace ConsoleApplication1
 6{
 7    class Program
 8    {
 9        static void Main(string[] args)
10        {
11            //得到指定的数字
12            int a = Int32.Parse(Console.ReadLine());
13
14            //经过运算后的总值,但是只保存最后三位。
15            int sum = a;
16
17            //保存所有X的值时尾数的大小
18            int[] v = new int[1000];
19
20            //求X的最小值,使得A^X大于1000
21            int x = 1;
22            
23            if (a < 1000)
24            {
25                x = getMinX(a);
26            }

27
28            for (int i = 0; i < x; i++)
29            {
30                sum = getSumA(sum, a);
31            }

32
33            //不断地给X加1,记录A^X的末尾3位数的值和X的值,直到A^X的末尾3位数出现重复的数字
34            do
35            {
36                v[sum] = x;
37                sum = getSumA(sum, a);
38                x++;
39            }
 while (v[sum] == 0);
40
41            //将当前X和值与原先记录A^X的末尾3位数的值的X值相加,输出最终的结果
42            Console.WriteLine(x + v[sum]);
43        }

44
45        /// <summary>
46        /// 得到sum 与 a 相乘后的最后三位数
47        /// </summary>
48        /// <param name="p"></param>
49        /// <returns></returns>

50        private static int getSumA(int sum, int a)
51        {
52            return getLast3Num(getLast3Num(sum) * getLast3Num(a));
53        }

54
55        /// <summary>
56        /// 得到P的最后三位数
57        /// </summary>
58        /// <param name="p"></param>
59        /// <returns></returns>

60        private static int getLast3Num(int p)
61        {
62            if (p >= 1000)
63            {
64                string t = p.ToString();
65                string s = t.Substring(t.Length - 3);
66                return Int32.Parse(s);
67            }

68
69            return p;
70        }

71
72        /// <summary>
73        /// 求X的最小值,使得A^X大于1000
74        /// </summary>
75        /// <param name="p"></param>
76        /// <returns></returns>

77        private static int getMinX(int p)
78        {
79            return (int)(Math.Log(1000/ Math.Log(p)) + 1;
80        }

81    }

82}

83

测试结果:
输入25,输出7
输入125,输出6
输入1000,输出3
输入1111111,输出52
输入1000003,输出102
输入123454321,输出27
posted @ 2008-03-04 08:25 逖靖寒 阅读(402) 评论(12)  编辑 收藏 所属分类: .NET 编程算法

  回复  引用  查看    
#1楼 2008-03-04 08:45 | floodpeak      
说两个问题
1.当x最小时,一定能保证x+y最小吗,如果可以请给出证明
2.你判定尾数相等的机制过于浪费空间,new了一个1000的int数组,而真正用到的只是其中的一个,其它都用作判定条件,不大合适
  回复  引用  查看    
#2楼 2008-03-04 08:56 | 毁于随      
没有审明白题....
  回复  引用  查看    
#3楼 [楼主]2008-03-04 09:01 | 逖靖寒      
@floodpeak
首先回答你的第二个问题
一个1000的int数组 是用于保存sum的最后三位的数组,而不是只用到了其中的一个。
如x = 2时,sum = 1024 则v[24] = 2
x = 3 -> sum = 2048 -> v[48] = 3
x = 4 -> sum = 4096 -> v[96] = 4
... ... ...
一旦v[sum的最后三位] != 0,说明sum的最后三位数出现了重复,这样就可以求出X+Y的最小值了。
这同时也证明了第一问,可以保证X+Y最小。

谢谢。
  回复  引用  查看    
#4楼 2008-03-04 09:23 | floodpeak      
@逖靖寒
刚才对于你数组的功能理解的不全
如你所讲空间浪费依然严重,建议使用hashtable
对于第一个问题,我举个例子,按照你的想法比如某个数当它的x达到12遇到了尾数相同的条件,于是退出了循环,而数组中的v[sum]可能是10,那是否有可能当x达到15时也遇到了尾数相同的条件,而v[sum]是4
由于你已退出循环,不可能发现后面的这种情况,而输出了不正确的结果
  回复  引用  查看    
#5楼 [楼主]2008-03-04 09:50 | 逖靖寒      
@floodpeak
--引用--------------------------------------------------
如你所讲空间浪费依然严重,建议使用hashtable
--------------------------------------------------------
恩,用hashtable也是一个不错的选择

--引用--------------------------------------------------
对于第一个问题,我举个例子,按照你的想法比如某个数当它的x达到12遇到了尾数相同的条件,于是退出了循环,而数组中的v[sum]可能是10,那是否有可能当x达到15时也遇到了尾数相同的条件,而v[sum]是4
由于你已退出循环,不可能发现后面的这种情况,而输出了不正确的结果
--------------------------------------------------------
不会输出不正确的结果。如当X=12时,sum的最后三个尾数和v[sum]=10的相等,那么让Y=10,X+Y就一定是最小。
当一个数的末尾三位数一定时,它的下一次幂的末尾三位数一是一定的。这就是说,当第一次出现重复的数字时,就是我们需要的X和Y的值了。

  回复  引用  查看    
#6楼 2008-03-04 10:20 | floodpeak      
恩,我刚才举的例子不会发生
假如x和y最后三个尾数相同,那么x+1和y+1也一定相同,因此找到的第一对儿就是和最小的

  回复  引用  查看    
#7楼 2008-03-04 11:09 | floodpeak      
刚才又想了想
我来证明一下我的第一个问题吧,反证法
m为第一个使得a上千的幂,存在x和y满足题目条件且x>m,使得x+y最小
由于x>m,所以a^x/a大于1000且尾数与a^y/a相同,所以x-1和y-1也满足题目条件
x-1 + y-1 < x+y
证出矛盾,所以x一定等于m,也即当x最小时,一定能保证x+y最小

有了这样的证明,程序就不用那么复杂了,因为知道这里的x一定是m,也就是你程序中getMinX返回的值,那么就把这个尾数记录下来,将x值不停++,当遇到尾数相同的x新值后,就找到了y,这样就不用什么数组和hashtable了
  回复  引用  查看    
#8楼 [楼主]2008-03-04 12:36 | 逖靖寒      
@floodpeak
--引用--------------------------------------------------
有了这样的证明,程序就不用那么复杂了,因为知道这里的x一定是m,也就是你程序中getMinX返回的值,那么就把这个尾数记录下来,将x值不停++,当遇到尾数相同的x新值后,就找到了y,这样就不用什么数组和hashtable了
--------------------------------------------------------

呵呵,你这个方法更棒!

  回复  引用  查看    
#9楼 2008-03-04 17:05 | 毁于随      
能不能给我讲讲要求,我有些没看懂.
  回复  引用  查看    
#10楼 [楼主]2008-03-04 21:48 | 逖靖寒      
@毁于随
题目描述:

从键盘输入一个int数A(A > 1),如果存在int数X和Y(X>Y),使得A^X和A^Y均大于1000,且他们的末尾三位数相等,则称X和Y是一对“A尾相等数”


这个已经说得很清楚了,您可以再耐心地看一看 :)
  回复  引用  查看    
#11楼 2008-03-05 17:02 | 毁于随      
我太笨了,还是没有看懂.

那个末尾三位数相等,是什么意思?
  回复  引用    
#12楼 2008-03-06 21:24 | Aaron.Guo [未注册用户]
@毁于随
您可以考虑一下1025 和 61025这两个数,他们的末尾三位数都是25。

标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-03-04 08:35 编辑过


相关链接: