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

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

2
1 6
2 99
OUTPUT
9
99
    解题报告:题意就不说了。我们每次计算平方后,保存前n位即可。这里我直接每次除10,直到这个数小于10^n。
    判换的话简单点直接用set,保存出现过的数,遇到重复则退出循环。代码如下:
 
   
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
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 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 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
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);
    }
}

你可能感兴趣的:(ACM,思维,Floyd判环)