思路:这个题一定会出现循环,所以一个个模拟,遇到相同的就再之前所有数中找最大的输出即可。
最容易想到的就是set判重,一开始k直接生算每次除十......超时
然后看了书,用string,ac,很方便但是时间达到了4s,果然string和stringstream好慢啊.........
又改成了记录k*k的每一位,时间为1s
最后用了floyd判圈算法,0.5s,空间复杂度为o(1)........果然神奇
先上set代码:
#include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<queue> #include<stack> #include<string> #include<map> #include<set> #include<sstream> using namespace std; #define LL long long //const int maxn = ; const int INF = 1000000000; //freopen("input.txt", "r", stdin); int buf[100]; LL next(LL n, LL k) { stringstream ss; ss << k * k; string s = ss.str(); if(s.length() > n) s = s.substr(0, n); LL ans; stringstream ss2(s); ss2 >> ans; return ans; } int main() { int t; scanf("%d", &t); while(t--) { set<LL> a; LL n, k; scanf("%lld%lld", &n, &k); LL ans = 0; while(!a.count(k)) { a.insert(k); ans = max(ans, k); k = next(n, k); } printf("%lld\n", ans); } return 0; }
然后是floyd判圈代码
#include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<queue> #include<stack> #include<string> #include<map> #include<set> #include<sstream> using namespace std; #define LL long long //const int maxn = ; const int INF = 1000000000; //freopen("input.txt", "r", stdin); int buf[100]; LL next(LL n, LL k) { if(!k) return 0; LL k2 = (LL)k * k; int L = 0; while(k2 > 0) {buf[L++] = k2 % 10; k2 /= 10;} if(n > L) n = L; int ans = 0; for(int i = 1; i < n; i++) ans = ans * 10 +buf[--L]; return ans; } int main() { int t; scanf("%d", &t); while(t--) { int n, k; cin >> n >> k; int ans = k; int k1 = k, k2 = k; do { k1 = next(n, k1); k2 = next(n, k2); if(k2 > ans) ans = k2; k2 = next(n, k2); if(k2 > ans) ans = k2; } while(k1 != k2); cout << ans << endl; } return 0; }
原文地址:http://blog.csdn.net/u014664226/article/details/45873929