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

来源:互联网 发布:淘宝联盟红包很无耻 编辑:程序博客网 时间:2024/06/03 20:24

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


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

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

就空间而言,Floyd判圈法<STL<哈希技术。

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


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

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

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

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

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

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


Floyd判圈法的代码

#include<bits/stdc++.h>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<bits/stdc++.h>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<bits/stdc++.h>using namespace std;typedef long long ll;ll n,k;set<ll>s;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;}


0 0
原创粉丝点击