UVa 11549 Calculator Conundrum 解题报告(判环)

来源:互联网 发布:怎样导出数据库 编辑:程序博客网 时间:2024/06/08 02:22

Problem C

CALCULATOR CONUNDRUM

Alice got a hold of an old calculator that can display n digits. She was bored enough to come up with the following time waster.

She enters a number k then repeatedly squares it until the result overflows. When the result overflows, only the most significant digits are displayed on the screen and an error flag appears. Alice can clear the error and continue squaring the displayed number. She got bored by this soon enough, but wondered:

“Given n and k, what is the largest number I can get by wasting time in this manner?”

Program Input

The first line of the input contains an integer (1 ≤ ≤ 200), the number of test cases. Each test case contains two integers (1 ≤ ≤ 9) and (0 ≤ < 10n) where n is the number of digits this calculator can display is the starting number.

Program Output

For each test case, print the maximum number that Alice can get by repeatedly squaring the starting number as described.

Sample Input & Output

INPUT

21 62 99
OUTPUT
999
    解题报告:题意就不说了。我们每次计算平方后,保存前n位即可。这里我直接每次除10,直到这个数小于10^n。
    判换的话简单点直接用set,保存出现过的数,遇到重复则退出循环。代码如下:
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <vector>#include <queue>#include <map>#include <set>#include <string>using namespace std;#define ff(i, n) for(int i=0;i<(n);i++)#define fff(i, n, m) for(int i=(n);i<=(m);i++)#define dff(i, n, m) for(int i=(n);i>=(m);i--)typedef long long LL;typedef unsigned long long ULL;void work();int main(){#ifdef ACM    freopen("in.txt", "r", stdin);#endif // ACM    work();}///////////////////////////////////////////int next(int n, int k){    LL res = (LL)k*k;    while(res >= n)        res/=10;    return res;}void work(){    int T;    scanf("%d", &T);    ff(cas, T)    {        int n, k;        scanf("%d%d", &n, &k);        n = (int)pow(10.0, n);        int ans = 1<<31;        set<int> ss;        while(1)        {            ans = max(ans, k);            if(ss.count(k))                break;            else                ss.insert(k);            k = next(n, k);        }        printf("%d\n", ans);    }}


    哈希应该也可以。然后《训练指南》上给出了一个Floyd判圈算法。简单来说就是速度为2的小朋友总会反追上速度为1的小朋友。时间上快了很多。代码如下:

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <vector>#include <queue>#include <map>#include <string>using namespace std;#define ff(i, n) for(int i=0;i<(n);i++)#define fff(i, n, m) for(int i=(n);i<=(m);i++)#define dff(i, n, m) for(int i=(n);i>=(m);i--)typedef long long LL;typedef unsigned long long ULL;void work();int main(){#ifdef ACM    freopen("in.txt", "r", stdin);#endif // ACM    work();}///////////////////////////////////////////int next(int n, int k){    LL res = (LL)k*k;    while(res >= n)        res/=10;    return res;}void work(){    int T;    scanf("%d", &T);    ff(cas, T)    {        int n, k;        scanf("%d%d", &n, &k);        n = (int)pow(10.0, n);        int ans = k;        int k1 = k, k2 = k;        do        {            k1 = next(n, k1);            k2 = next(n, k2);            ans = max(ans, k2);            k2 = next(n, k2);            ans = max(ans, k2);        } while(k1 != k2);        printf("%d\n", ans);    }}

0 0
原创粉丝点击