130831组队赛-Regionals 2011, Asia - Kuala Lumpur

A.Smooth Visualization

简单模拟题,不多说了。

 

#include<iostream>

#include<cstdio>

#include<algorithm>

#include<cstring>

#include<string>

#include<cmath>

#include<set>

#include<vector>

#include<stack>

#define mem(a,b) memset(a,b,sizeof(a))

#define FOR(a,b,i) for(i=a;i<=b;++i)

#define For(a,b,i) for(i=a;i<b;++i)

#define N 1000000007

using namespace std;

inline void RD(int &ret)

{

    char c;

    do

    {

        c=getchar();

    }

    while(c<'0'||c>'9');

    ret=c-'0';

    while((c=getchar())>='0'&&c<='9')

    {

        ret=ret*10+(c-'0');

    }

}

inline void OT(int a)

{

    if(a>=10)

    {

        OT(a/10);

    }

    putchar(a%10+'0');

}

int n;

char s[105];

int ss[705];

int main()

{

    int t;

    scanf("%d",&t);

    getchar();

    while(t--)

    {

        gets(s);

        int l = strlen(s);

        int ll = 0;

        int ma = 0;

        int a = s[0] - '0';

        ss[0] = a;

        ma = a;

        ll++;

        int b;

        for(int i=1;i<l;i++)

        {

            a = s[i-1] - '0';

            b = s[i] - '0';

            ma = max(ma,b);

            if(b == a)

            {

                ss[ll] = b;

                ll++;

            }

            if(b > a)

            {

                int c = a + 1;

                do

                {

                    ss[ll] = c;

                    c++;

                    ll++;

                }while(c <= b);

            }

            if(b < a)

            {

                int c = a - 1;

                do

                {

                    ss[ll] = c;

                    c--;

                    ll++;

                }while(c >= b);

            }

        }

        for(int i = ma;i >=1;i--)

        {

            for(int j=0;j<ll;j++)

            {

                if(i > ss[j]) printf("*");

                else printf("+");

            }

            printf("\n");

        }

    }

    return 0;

}

 


E.Social Holidaying

二分图匹配,题意是给你两个序列,要求A序列中最多有多少对数和为B序列中的数,且A序列中的数每个只能用一次,B序列的数可以无限次出现。

思路:可以将A序列中所有能组成的可能全都组合起来,如果B序列中有出现就开始搜索,把所有情况都搜出来。

 

#include<iostream>

#include<cstdio>

#include<algorithm>

#include<cstring>

#include<string>

#include<cmath>

#include<set>

#include<vector>

#include<stack>

#include<map>

#define mem(a,b) memset(a,b,sizeof(a))

#define FOR(a,b,i) for(i=a;i<=b;++i)

#define For(a,b,i) for(i=a;i<b;++i)

#define N 1000000007

using namespace std;

inline void RD(int &ret)

{

    char c;

    do

    {

        c=getchar();

    }

    while(c<'0'||c>'9');

    ret=c-'0';

    while((c=getchar())>='0'&&c<='9')

    {

        ret=ret*10+(c-'0');

    }

}

inline void OT(int a)

{

    if(a>=10)

    {

        OT(a/10);

    }

    putchar(a%10+'0');

}

map<long long,int>s;

vector<int>p[1001];

int vis[1001],tmp[1001];

long long x[1001],y;

int f(int j)

{

    int i,q;

    for(i=0;i<p[j].size();++i)

    {

        q=p[j][i];

        if(vis[q]==0)

        {

            vis[q]=1;

            if(tmp[q]==0||f(tmp[q])==1)

            {

                tmp[q]=j;

                return 1;

            }

        }

    }

    return 0;

}

int main()

{

    int t,i,j,sum,n,m;

    scanf("%d",&t);

    while(t--)

    {

        s.clear();

        scanf("%d%d",&n,&m);

        for(i=0;i<n;++i)

        {

            scanf("%lld",&x[i]);

        }

        for(i=0;i<m;++i)

        {

            scanf("%lld",&y);

            s[y]=1;

        }

        for(i=0;i<n;++i)

        {

            p[i].clear();

        }

        sum=0;

        for(i=0;i<n;++i)

        {

            for(j=0;j<n;++j)

            {

                if(i==j)

                {

                    continue;

                }

                if(s[x[i]+x[j]]==1)

                {

                    p[i].push_back(j);

                }

            }

        }

        mem(tmp,0);

        for(i=0;i<n;++i)

        {

            mem(vis,0);

            if(f(i)==1)

            {

                sum++;

            }

        }

        printf("%d\n",sum/2);

    }

    return 0;

}


G.Writings on the Wall

 

字符串问题,问的是前后两个字符串最多能重合部分几次。

方法有两种:kmp和hash

KMP写法:

 

#include<iostream>

#include<cstdio>

#include<algorithm>

#include<cstring>

#include<string>

#include<cmath>

#include<set>

#include<vector>

#include<stack>

#define mem(a,b) memset(a,b,sizeof(a))

#define FOR(a,b,i) for(i=a;i<=b;++i)

#define For(a,b,i) for(i=a;i<b;++i)

//#define N 1000000007

using namespace std;

inline void RD(int &ret)

{

    char c;

    do

    {

        c=getchar();

    }

    while(c<'0'||c>'9');

    ret=c-'0';

    while((c=getchar())>='0'&&c<='9')

    {

        ret=ret*10+(c-'0');

    }

}

inline void OT(int a)

{

    if(a>=10)

    {

        OT(a/10);

    }

    putchar(a%10+'0');

}

#define N 50005

char a[N];

char b[N];

int next[N];

int l1,l2;

void update()

{

    next[0] = -1;

    int i=0,j=-1;

    while(i<l2)

    {

        while(j>=0&&b[i]!=b[j])

        {

            j=next[j];

        }

        i++;

        j++;

        next[i]=j;

    }

}

int main()

{

    int t,i,j,ans;

    scanf("%d",&t);

    while(t--)

    {

        scanf("%s%s",a,b);

        l1=strlen(a);

        l2=strlen(b);

        update();

        i=0;

        j=0;

        while(i<l1)

        {

            while(j>=0&&a[i]!=b[j])

            {

                j=next[j];

            }

            i++;

            j++;

            if(j==l2&&i<l1)

            {

                j=next[j];

            }

        }

        ans=0;

        while(j>=0)

        {

            j=next[j];

            ans++;

        }

        printf("%d\n",ans);

    }

    return 0;

}

HASH写法:

 

 

#include<iostream>

#include<cstdio>

#include<algorithm>

#include<cstring>

#include<string>

#include<cmath>

#include<set>

#include<vector>

#include<stack>

#include <queue>

#include<map>

#define mem(a,b) memset(a,b,sizeof(a))

#define FOR(a,b,i) for(i=a;i<=b;++i)

#define For(a,b,i) for(i=a;i<b;++i)

using namespace std;

inline void RD(int &ret)

{

    char c;

    do

    {

        c=getchar();

    }

    while(c<'0'||c>'9');

    ret=c-'0';

    while((c=getchar())>='0'&&c<='9')

    {

        ret=ret*10+(c-'0');

    }

}

inline void OT(int a)

{

    if(a>=10)

    {

        OT(a/10);

    }

    putchar(a%10+'0');

}

int main()

{

    int i,j,l1,l2,t,sum;

    long long x,y,z;

    char a[50001],b[50001];

    RD(t);

    while(t--)

    {

        scanf("%s%s",a,b);

        l1=strlen(a);

        l2=strlen(b);

        i=l1-1;

        j=0;

        z=1;

        x=0;

        y=0;

        sum=1;

        while(i>=0&&j<l2)//hash过程

        {

            x+=z*(a[i]-'a');

            z*=33;

            y*=33;

            y+=(b[j]-'a');

            i--;

            j++;

            if(x==y)

            {

                sum++;

            }

        }

        printf("%d\n",sum);

    }

    return 0;

}


H.Robotic Traceur

 

最短路,我们悲剧地居然一直TLE,后来才发现BFS,SPFA,甚至连暴搞都可以过。。。

 

#include<iostream>

#include<cstdio>

#include<algorithm>

#include<cstring>

#include<string>

#include<cmath>

#include<set>

#include<vector>

#include<stack>

#include <queue>

#include<map>

#define mem(a,b) memset(a,b,sizeof(a))

#define FOR(a,b,i) for(i=a;i<=b;++i)

#define For(a,b,i) for(i=a;i<b;++i)

using namespace std;

inline void RD(int &ret)

{

    char c;

    do

    {

        c=getchar();

    }

    while(c<'0'||c>'9');

    ret=c-'0';

    while((c=getchar())>='0'&&c<='9')

    {

        ret=ret*10+(c-'0');

    }

}

inline void OT(int a)

{

    if(a>=10)

    {

        OT(a/10);

    }

    putchar(a%10+'0');

}

struct xl

{

    double x,y;

}v[1001];

double dis(int i, int j)

{

    return sqrt((v[i].x-v[j].x)*(v[i].x-v[j].x)+(v[i].y-v[j].y)*(v[i].y-v[j].y));

}

int main()

{

    int t,n,s,tmp,i,id[1001],l[1001],w,res;

    double p,q;

    RD(t);

    while(t--)

    {

        scanf("%d%d%d%lf%lf",&n,&s,&tmp,&p,&q);

        p+=q;

        FOR(1,n,i)

        {

            scanf("%lf%lf",&v[i].x,&v[i].y);

            id[i]=-1;

        }

        id[s]=0;

        l[0]=s;

        w=1;

        res=0;

        while(res<w)

        {

            s=l[res];

            FOR(1,n,i)

            {

                if(id[i]<0&&dis(s,i)<p+1e-6)

                {

                    id[i]=id[s]+1;

                    l[w++]=i;

                    if(i==tmp)

                    {

                        break;

                    }

                }

            }

            res++;

        }

        if(id[tmp]>=0)

        {

            printf("%d\n",id[tmp]);

        }

        else

        {

            printf("Impossible\n");

        }

    }

    return 0;

}


I.Shortest Leash

 

应该是一道dp题,它要求狗可以选择多个向量的正负方向走,问最远能与远点的距离为多少。。。

我是用随机算法过的,目的在于将所有的向量打乱,使其在加上向量时,能够会在一次中找到正解。

 

#include<iostream>

#include<cstdio>

#include<algorithm>

#include<cstring>

#include<string>

#include<cmath>

#include<set>

#include<vector>

#include<stack>

#include<map>

#define mem(a,b) memset(a,b,sizeof(a))

#define FOR(a,b,i) for(i=a;i<=b;++i)

#define For(a,b,i) for(i=a;i<b;++i)

using namespace std;

struct xl

{

    double x,y;

} p[101],q,l,r;

double dis(xl a)

{

    return sqrt(a.x*a.x+a.y*a.y);

}

int main()

{

    int t,i,j,z[101];

    double ans;

    while(scanf("%d",&t))

    {

        if(t==0)

        {

            break;

        }

        for(i=0; i<t; ++i)

        {

            scanf("%lf%lf",&p[i].x,&p[i].y);

        }

        ans=0;

        for(j=0;j<=10000;++j)

        {

            random_shuffle(p,p+t);//随机打乱数组

            q.x=0;

            q.y=0;

            for(i=0; i<t; ++i)

            {

                l=q;

                r=q;

                l.x+=p[i].x;

                l.y+=p[i].y;

                r.x-=p[i].x;

                r.y-=p[i].y;

                if(dis(l)>dis(r))

                {

                    q=l;

                }

                else

                {

                    q=r;

                }

                ans=max(ans,dis(q));

            }

        }

        printf("%.3f\n",ans);

    }

    return 0;

}



 

 

你可能感兴趣的:(reg)