1. 程式人生 > >uva 11549 Calculator Conundrum

uva 11549 Calculator Conundrum

break span 做的 class 循環 跑步 過程 continue 看到了

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 }

uva 11549 Calculator Conundrum