暴力,STL,哈希技术,Floyd判圈算法(计算器谜题,uva 11549)

想了老半天,只会暴力,然后就过了。。


实现由三种方法,一是STL,而是哈希技术,三是Floyd判圈法。

就速度而言,Floyd判圈法>哈希技术>STL。分别跑了70ms,180ms,480ms。STL真是慢的可以。

就空间而言,Floyd判圈法

也就是说,STL与哈希技术在空间和时间上各有千秋,但Floyd判圈法完爆一切= =。


关于Floyd判圈法的一些理解。

Floyd判圈法不需要开任何储存空间。

时间上也不需要调用STL那么笨重的东西,也不需要像哈希技术那样循环检查。

可以理解为优化了空间,同时也就优化了时间。

本质是让他们都跑起来,而且一个比另一个快。都跑起来才能都进入圈里。一个比另一个快才可能相遇。

慢的速度取1,快的速度取2。每次更新花费时间最少,而且最多花一圈就能追上。


Floyd判圈法的代码

#include
using namespace std;
typedef long long ll;

inline ll mp(ll x,ll n)
{
    ll ret=1;
    while(n)
    {
        if(n&1) ret*=x;
        x*=x;
        n>>=1;
    }
    return ret;
}

inline ll NEXT(ll x,ll r)
{
    x*=x;
    while(x>=r) x/=10;
    return x;
}

int main()
{
    ll t;
    scanf("%lld",&t);
    while(t--)
    {
        ll n,k;
        scanf("%lld %lld",&n,&k);
        ll k1=k;
        ll k2=k;
        ll ans=k;
        ll r=mp(10,n);
        do
        {
            k1=NEXT(k1,r);
            k2=NEXT(k2,r);ans=max(ans,k2);
            k2=NEXT(k2,r);ans=max(ans,k2);
        }while(k1!=k2);
        printf("%lld\n",ans);
    }
    return 0;
}
哈希技术的代码

#include
using namespace std;
typedef long long ll;

inline ll mp(ll x,ll n)
{
    ll ret=1;
    while(n)
    {
        if(n&1) ret*=x;
        x*=x;
        n>>=1;
    }
    return ret;
}

inline ll NEXT(ll x,ll r)
{
    x*=x;
    while(x>=r) x/=10;
    return x;
}

const ll hashsize=1000005;
const ll maxstate=1000005;
ll head[hashsize];
struct node
{
    ll v,next;
}Node[maxstate];
ll tot;
inline void init()
{
    tot=0;
    memset(head,-1,sizeof(head));
}
inline ll add(ll s)
{
    ll h=s%1000000;
    for(ll i=head[h];i!=-1;i=Node[i].next)
        if(Node[i].v==s) return 0;
    Node[tot].v=s;
    Node[tot].next=head[h];
    head[h]=tot++;
    return 1;
}
int main()
{
    ll t;
    scanf("%lld",&t);
    while(t--)
    {
        ll n,k;
        scanf("%lld %lld",&n,&k);
        ll r=mp(10ll,n);
        init();
        ll MAX=k;
        while(add(k))
        {
            k=NEXT(k,r);
            MAX=max(MAX,k);
        }
        printf("%lld\n",MAX);
    }
    return 0;
}

STL的代码(编码十分简单)

#include
using namespace std;
typedef long long ll;

ll n,k;
sets;

ll mp(ll x,ll n)
{
    ll ret=1;
    while(n)
    {
        if(n&1) ret*=x;
        x*=x;
        n>>=1;
    }
    return ret;
}

int main()
{
    ll t;
    scanf("%lld",&t);
    while(t--)
    {
        scanf("%lld %lld",&n,&k);
        ll r=mp(10ll,n);
        s.clear();
        while(!s.count(k))
        {
            s.insert(k);
            k*=k;
            while(k>=r) k/=10;
        }
        printf("%lld\n",*(--s.end()));
    }
    return 0;
}


你可能感兴趣的:(大白书-第1章-算法设计基础,暴力,STL,哈希技术,Floyd判圈算法)