UVA 11549 Calculator Conundrum

本文深入探讨了循环计算过程中的关键特性,通过两个核心要点揭示了如何有效识别循环,并利用Floyd判圈法优化算法效率。详细阐述了算法的具体实现步骤,包括初始化阶段、循环检测及优化策略,旨在提高复杂度分析和解决实际问题的能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目地址

 

本题把握两点:

1.    按本题计算下去肯定是一个循环的过程。因为显示的位数是的,所有下一次的输入值在给定整数区间内。两种情况,计算某一输入值后与之前计算过的值重叠,得循环。第        二 种情况,或者说是极端情况,一直未遇到重复的数字,则最终区间内所有的数都已经被访问一次,接下来的输入值一定是区间内的值,得循环。综上最终一定会有循环。

2.    第二点是优化,有关于Floyd判圈法。因为最终一定是循环,则只要选取非循环部分和循环部分中的最大值,即可。如果按一般方法,保存所有中间值,如果当前值在之前已经出现过则出现环,种植,但这种方法复杂度为O(n^2)。如果只需要判断是否存在环,只需要按照Floyd判圈法,其复杂度为O(n)。两个人围田径场跑,一个人是另一个人的两倍速度,则最终两人一定会在起点相遇,如果相遇则一定出现了环,否则两倍速度的一定一直领先。

       这里关于Floyd判圈法还有一点要注意,如果要记录所有路径过程中的节点,一定只能按照一倍速度访问的节点!

 

 

#include <cstdlib>
#include <iostream>
#include <stdio.h>

using namespace std;

long long m;

long long for_ward(int n,long long k,int step)
{
    long long pos = k;
    long len = 1;
    for(int i = 1; i < n; i++)len *= 10;
    
    for(int i = 0; i < step; i++)
    {
        pos *= pos;
        long j = 10;
        while(pos/len >= 10)
        {
            pos /= 10;
        }
        
        if(pos > m)m = pos;
    }
  
  
    return pos;
}

void caculate(long n, long k)
{
    long long one,two;
    one = two = k;
    m = k;
    do
    {
        one = for_ward(n,one,1);//m = max(m, one);
        two = for_ward(n,two,2);//m = max(m, two);
    }while(one !=  two);
    
    printf("%lld\n",m);
} 

int main(int argc, char *argv[])
{
    long t,n,k;
    scanf("%ld",&t);
    while(t--)
    {
        scanf("%ld%ld",&n, &k);
        caculate(n,k);
    } 
    
    //system("PAUSE");
    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值