UVa11549:Calculator Conundrum
阿新 • • 發佈:2018-02-01
spa 答案 訓練指南 快的 str tdi class 所有 跑步
UVa11549:Calculator Conundrum
題目大意
有一個老舊的計算器只能顯示前n個數字。現在給定一個數字k,每次給k平方,如果答案長度超過n則從最高位開始顯示n個數字,丟棄其余數字。
要求:求出計算器能顯示的最大數字。
Solution1(naive)
本題中得到的數列會出現循環,可以用一個set記錄所有得到的數字,一旦出現重復數字停止循環,輸出set中的最大值即可。
AC-Code(C++)
Time:540ms
#include <iostream> #include <iomanip> #include <algorithm> #include <string> #include <cstring> #include <map> #include <set> #include <vector> #include <cmath> #include <climits> #include <ctime> using namespace std; typedef long long ll; const int INF = 0x3f3f3f3f; const double PI = acos(-1.0); const int maxn = 30000 + 10; /* * 劉汝佳 訓練指南 P42 */ int n,k,mask; int getNext(int x){ ll temp = (ll)x * x; while(temp >= mask) temp /= 10; return (int)temp; } int main(int argc, const char * argv[]) { // freopen("input.txt", "r", stdin); int T; scanf("%d",&T); while(T--){ scanf("%d %d",&n,&k); mask = 1; for(int i=0;i<n;i++) mask *= 10; set<int> s; int ans = k; while(s.count(k)==0){ s.insert(k); k = getNext(k); ans = max(ans,k); } printf("%d\n",ans); } return 0; }
Solution2(floyd判圈法)
想象兩個人賽跑,兩人以不同的速度勻速運動。如果賽道是直線的,那麽兩個人以後再也不會相遇了,而如果兩個人在一個環形賽道上跑步,那麽速度快的那個人一定會在某一時刻從後面追上速度慢的那個人。
在這裏循環的序列就是環形賽道,這種方法叫做floyd判圈法,這樣做後因為不需要頻繁的在set中查詢元素是否存在,所以運行速度有了很大的提升,並且還將空間復雜度降為Ο(1)。
Note
在判圈的時候最開始我很順的寫出了如下代碼,但這樣會造成個別點沒有取到就退出循環了,所以某些測試例子中的出的答案往往要比正確答案稍微小一點。
// wrong do{ k1 = getNext(k1); k2 = getNext(getNext(k2)); ans = max(ans,max(k1,k2)); }while(k1 != k2);
AC-Code(C++)
Time:50ms
#include <iostream> #include <iomanip> #include <algorithm> #include <string> #include <cstring> #include <map> #include <set> #include <vector> #include <cmath> #include <climits> #include <ctime> using namespace std; typedef long long ll; const int INF = 0x3f3f3f3f; const double PI = acos(-1.0); const int maxn = 30000 + 10; int n,k,mask; /* * 劉汝佳 訓練指南 P42 */ int getNext(int x){ ll temp = (ll)x * x; while(temp >= mask) temp /= 10; return (int)temp; } int main(int argc, const char * argv[]) { // freopen("input.txt", "r", stdin); int T; scanf("%d",&T); while(T--){ scanf("%d %d",&n,&k); mask = 1; for(int i=0;i<n;i++) mask *= 10; int k1 = k; int k2 = k; int ans = k; // wrong // do{ // k1 = getNext(k1); // k2 = getNext(getNext(k2)); // ans = max(ans,max(k1,k2)); // }while(k1 != k2); // right do{ k1 = getNext(k1); k2 = getNext(k2); ans = max(ans,k2); k2 = getNext(k2); ans = max(ans,k2); }while(k1 != k2); printf("%d\n",ans); } return 0; }
UVa11549:Calculator Conundrum