uva 11549 Calculator Conundrum

https://vjudge.net/problem/UVA-11549

题意:

有一个老式计算器,只能显示n位数字。输入一个整数k,不断地平方,直到溢出。每次溢出的时候,会不断的显示最高n位和错误标记,之后错误标记会清除,继续平方。求在这个过程中出现的最大的数字。

思路:

首先,手算了几个例子,发现最后会产生循环,于是我就用map记录每个数字的出现,直到出现重复为止,然后输出map中的最大值。

代码:

 1 #include <stdio.h>
 2 #include <map>
 3 using namespace std;
 4 typedef long long ll;
 5 map<ll,bool> mmp;
 6 
 7 ll mpow(int b,int n)
 8 {
 9     if (n == 0) return 1;
10 
11     long long ans = mpow(b, n / 2);
12 
13     ans *= ans;
14 
15     if (n & 1) ans *= b;
16 
17     return ans;
18 }
19 
20 int cal(long long k)
21 {
22     int cnt = 0;
23 
24     while (k)
25     {
26         k /= 10;
27         cnt++;
28     }
29 
30     return cnt;
31 }
32 
33 int main()
34 {
35     int t;
36 
37     scanf("%d",&t);
38 
39     while (t--)
40     {
41         mmp.clear();
42 
43         int n;
44         long long k;
45 
46         scanf("%d%lld",&n,&k);
47 
48 
49 
50         long long m = mpow(10,n);
51 
52         if (k == 0)
53         {
54             printf("0\n");
55 
56             continue;
57         }
58 
59         if (k == 1)
60         {
61             printf("1\n");
62 
63             continue;
64         }
65 
66 
67         while (1)
68         {
69             if (k == 1 || mmp[k]) break;
70 
71             mmp[k] = 1;
72 
73             k *= k;
74 
75             int cnt = cal(k);
76 
77             if (cnt <= n) continue;
78 
79             k /= mpow(10,cnt - n);
80 
81             //printf("%lld *\n",k);
82         }
83 
84         printf("%lld\n",mmp.rbegin()->first);
85     }
86 
87     return 0;
88 }

之后看到了lrjjj的做法,用了一个叫做floyd判圈法的方法,就是在一个环形跑道上,两个小孩子跑步,一个孩子的速度是另外一个的两倍,那么如果同时出发的话,快的孩子会超越慢的孩子,并在某一时刻两人会相遇。

这题呢,就是一个循环,那么定义两个起始的数,一个每次变换一次,一个每次变换两次,那么两个数相等的时候就可以跳出循环,一个循环当中的所有数字肯定都遍历完了。这个方法主要是有着优秀的空间复杂度为O(1)。

但是它的时间复杂度也比用map优秀:

这是用floyd判圈法做的

这是用map做的

代码:

 1 #include <stdio.h>
 2 
 3 long long mpow(long long b,int n)
 4 {
 5     if (n == 0) return 1;
 6 
 7     long long ans = mpow(b,n / 2);
 8 
 9     ans *= ans;
10 
11     if (n & 1) ans *= b;
12 
13     return ans;
14 }
15 
16 int cal(long long k)
17 {
18     int cnt = 0;
19 
20     while (k)
21     {
22         cnt++;
23         k /= 10;
24     }
25 
26     return cnt;
27 }
28 
29 long long nex(long long k,int n)
30 {
31     k *= k;
32 
33     int cnt = cal(k);
34 
35     if (cnt <= n) return k;
36 
37     k = k / mpow(10,cnt - n);
38 
39     return k;
40 }
41 
42 int main()
43 {
44     int t;
45 
46     scanf("%d",&t);
47 
48     while(t--)
49     {
50         int n;
51         long long k;
52 
53 
54         scanf("%d%lld",&n,&k);
55 
56         long long ans = k;
57 
58         long long k1 = k,k2 = k;
59 
60         do
61         {
62             k1 = nex(k1,n);if (k1 > ans) ans = k1;
63             k2 = nex(k2,n);if (k2 > ans) ans = k2;
64             k2 = nex(k2,n);if (k2 > ans) ans = k2;
65 
66         }while (k1 != k2);
67 
68         printf("%lld\n",ans);
69     }
70 
71     return 0;
72 }

 

posted @ 2017-10-02 15:42  qrfkickit  阅读(224)  评论(0编辑  收藏  举报