Summer day 16——UVa 11549相关

题意:有个老式计算器,每次只能记住一个数字的前n位。现在输入一个整数k,然后反复平方,一直做下去,能得到的最大数是多少。例如,n=1,k=6,那么一次显示:6,3,9,1…
从这道题拓展一下~
首先是

Floyd判圈法:

Floyd判圈算法(Floyd Cycle Detection Algorithm),又称龟兔赛跑算法(Tortoise and Hare Algorithm)。该算法由美国科学家罗伯特·弗洛伊德发明,是一个可以在有限状态机、迭代函数或者链表上判断是否存在环,求出该环的起点与长度的算法。

如果有限状态机、迭代函数或者链表上存在环,那么在某个环上以不同速度前进的2个指针必定会在某个时刻相遇。同时显然地,如果从同一个起点(即使这个起点不在某个环上)同时开始以不同速度前进的2个指针最终相遇,那么可以判定存在一个环,且可以求出2者相遇处所在的环的起点与长度。

说了这么多,实现来说就是
kid1 = next();
kid2 = next(); judge();
kid2 = next(); judge();
kid1!=kid2时的循环。

这是一个找节点的高效算法时间按复杂度为O(m+n),为线性复杂度。

C++ set

集合:include< set >;调用:set< TYPENAME > NAME;
常用操作有insert, begin, end, count, erase等。
Reference
时间复杂度即是查找的时间复杂度,空间复杂度为O(n)。

题解

// set
#include<cstdio>
#include<set>
using namespace std;
int T,n,k;
int next(int x)//寻找x的后继
{
    if(!k) return 0;
    int buf[20],i=0;
    long long t=(long long)x*x;
    while(t)
    {
        buf[i++]=t%10;
        t/=10;
    }
    int ans=0;
    for(int j=1;j<=min(n,i);++j) ans=ans*10+buf[i-j];
    return ans;
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&k);
        set<int> S;
        while(!S.count(k))
        {
            S.insert(k);
            k=next(k);
        }
        printf("%d\n",*(--S.end()));
    }
    return 0;
}
//Floyd
#include<cstdio>
#include<set>
using namespace std;
int T,n,k;
int next(int x)
{
    if(!k) return 0;
    int buf[20],i=0;
    long long t=(long long)x*x;
    while(t)
    {
        buf[i++]=t%10;
        t/=10;
    }
    int ans=0;
    for(int j=1;j<=min(n,i);++j) ans=ans*10+buf[i-j];
    return ans;
}
int main()
{
    freopen("in.txt","r",stdin);
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&k);
        int ans=max(k,next(k)),k1=k,k2=next(k);//k1是第一个小孩,k2是第二个小孩
        while(k1!=k2)
        {
            k1=next(k1);
            k2=next(k2); if(k2>ans) ans=k2; //小孩跑第一次
            k2=next(k2); if(k2>ans) ans=k2; //小孩跑第二次
        }
        printf("%d\n",ans);
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值