坦然玲子  

 

K尾相等数

时间限制:3000 ms  |  内存限制:65535 KB
难度:1
 
描述
输入一个自然数K(K>1),如果存在自然数M和N(M>N),使得K^M和K^N均大于等于1000,且他们的末尾三位数相等,则称M和N是一对“K尾相等数”。下面请编程求出M+N最小的K尾相等数。
 
输入
第一行包含一个正整数T,T<10000,表示有T组数据;
随后有N行,每行包括一个整数K(K<2*10^10);
输出
对于输入的每个整数K,输出对应的M+N的最小值;
样例输入
1
2
样例输出
120
 
测试数据

25

125

1000

1234

111111

1000003

123454321

测试数据结果:

7

6

3

56

52

102

27  

 

分析

1.上面的要点中,1,2,3,5,6都是辅助条件,关键是弄清楚第4点。末尾三位相等是什么意思?比如 123456 末尾三位是 ‘456’ 而 45678 末尾三位则是‘678’。显然(虽然我也不喜欢在书上看到这个字眼,但是这里确实是很显然……),这里指的是10进制数的末尾3位,如何取末尾3位的数字?很显然( =.=! )将这个数字对1000求模就可以了。

2.仔细思考后,我们可以注意到,任何数对1000求模只有1000种可能(0~999),所以我们将K^Power 中的Power从1(为什么不是0?因为K^0=1<1000,而我们不考虑小于1000的情况,题解第3点)到1001逐个求值,总有相等的两个数字。因为结果只有1000种可能,但是有1001次求值,哪怕前1000次所求结果都不一样,最后一次的值必然与前面1000种其中的一种相等(相关知识:抽屉原理1)。

代码:

 

 1 #include <iostream>
 2 #include <memory>
 3 #include<cstring>
 4  
 5 using namespace std;
 6 
 7 int Record[1000];      // 用以记录的一维数组
 8  
 9 int KTail( int K )
10 {
11      memset( Record, 0, sizeof(Record) );      
12      int Product = 1;                          
13      bool bTakeRecord = false;                 // 需要一个标记,用以判断是否>=1000
14      if ( K>=1000 )
15      {
16          bTakeRecord = true;
17          K=K%1000;                  
18      }                               
19  
20      for ( int Power = 1; Power<=1001; ++ Power)    
21 
22      {
23          Product *= K;               // Product = (K^Power-1)%1000 * K 
24          if ( bTakeRecord || Product>=1000 )     // 必须符合题目的条件 K^Power>=1000
25          {
26               bTakeRecord = true;               // 考虑到有可能之前是false,再赋值
27               Product = Product%1000;           
28               
29               if ( Record[Product]==0 )         
30 
31                    Record[Product] = Power;    
32 
33               else
34                    return Power + Record[Product];   
35 
36          }
37      }
38  
39      return -1;       // 这行其实可以不写,因为不可能到这里,但是为了不让编译器提示编译警告
40                       // 信息,还是加上吧。
41 }
42  
43 int main()
44 {
45      int t,k;
46   cin>>t;
47      while(t--)  
48 
49      {
50          cin>>k;
51          cout<<KTail(k)<<endl;  // 输出结果
52      }
53  
54      return 0;
55 }

 

 

 

posted on 2012-03-11 13:08  坦然玲子  阅读(904)  评论(0编辑  收藏  举报