2013 ACM-ICPC杭州赛区全国邀请赛——题目重现

7 篇文章 0 订阅
1 篇文章 0 订阅

今天的比赛让我又回忆起了长沙被虐的那次。。。感觉比长沙那次做起来相对轻松不少。。。

1001 Robot 

一道概率题,总共只有m*n的复杂度,每次遍历1~n的位置上的概率分布,再得到相应的下一位的概率,最后只要将l~r区间内的概率相加即可,直接数组可能会MLE,建议使用滚动数组。ORZ Baoge :传送门

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
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 w,m,n,l,r,a,b;
double ans,p[2][201];
int main()
{
    int i,j;
    while(1)
    {
        RD(n);
        RD(m);
        RD(l);
        RD(r);
        if(m==0&&n==0&&l==0&&r==0)
        {
            break;
        }
        memset(p,0.0,sizeof(p));
        p[0][1]=1.0;//初始位置概率为1
        for(i=1; i<=m; ++i)
        {
            RD(w);
            for(j=1; j<=n; ++j)
            {
                if(p[0][j]==0)
                {
                    continue;
                }
                a=j+w;
                while(a>n)//注意边界
                {
                    a-=n;
                }
                b=j-w;
                while(b<=0)
                {
                    b+=n;
                }
                p[1][a]+=p[0][j]*0.5;//注意是+=,将之前的和得到的相加
                p[1][b]+=p[0][j]*0.5;
            }
            for(j=1; j<=n; ++j)//滚动数组
            {
                p[0][j]=p[1][j];
                p[1][j]=0;
            }
        }
        ans=0;
        for(i=l;i<=r;++i)
        {
            ans+=p[0][i];
        }
        printf("%.4f\n",ans);
    }
    return 0;
}

1002 X-Boxes

赛后AC的,发现是java大数除法,果然需要全面发展的啊。。。

import java.io.*;
import java.math.*;
import java.util.*;
import java.text.*;
public class Main
{
    public static void main(String[] args)
    {
        Scanner cin=new Scanner(System.in);
        BigInteger s,n,tmp;
        int i,k,t,p;
        t=cin.nextInt();
        while(t>0)
        {
            t--;
            n=cin.nextBigInteger();
            k=cin.nextInt();
            s=new BigInteger("0");
            p=1;
            for(i=1; i<k; i++)
            {
                p*=2;
            }
            while(true)
            {
                n=n.divide(BigInteger.valueOf(p));
                tmp=n.subtract(n.divide(BigInteger.valueOf(2)));
                if(tmp.compareTo(BigInteger.ZERO)==0)
                {
                    break;
                }
                s=s.add(tmp);
                n=n.divide(BigInteger.valueOf(2));
            }
            System.out.println(s);
        }
    }
}

1003 Transformation

线段树区间处理,数据结构果然很神,让我的输入输出优化有了充分的用武之地。。。MB Baoge的手写线段树。。。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
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
{
    int l,r;
    long long vis;
} s[400000];
int n,m,c,x,y;
long long p;//注意是long long不然会WA
void build(int ll,int rr,int tmp)
{
    int mid;
    s[tmp].l=ll;
    s[tmp].r=rr;
    s[tmp].vis=-1;
    if(ll==rr)
    {
        return;
    }
    else
    {
        mid=(ll+rr)/2;
        build(ll,mid,tmp*2);
        build(mid+1,rr,tmp*2|1);
    }
}
void push(int tmp)
{
    s[tmp*2].vis=s[tmp*2|1].vis=s[tmp].vis;
    s[tmp].vis=-1;
}
void up1(int ll,int rr,int tmp,long long id)
{
    if(s[tmp].l==ll&&s[tmp].r==rr&&s[tmp].vis!=-1)
    {
        s[tmp].vis+=id;
        s[tmp].vis=s[tmp].vis%10007;
    }
    else
    {
        if(s[tmp].vis!=-1)
        {
            push(tmp);
        }
        int mid=(s[tmp].l+s[tmp].r)/2;
        if(ll>mid)
        {
            up1(ll,rr,tmp*2|1,id);
        }
        else if(rr<=mid)
        {
            up1(ll,rr,tmp<<1,id);
        }
        else
        {
            up1(ll,mid,tmp*2,id);
            up1(mid+1,rr,tmp*2|1,id);
        }
    }
}
void up2(int ll,int rr,int tmp,long long id)
{
    if(s[tmp].l==ll&&s[tmp].r==rr&&s[tmp].vis!=-1)
    {
        s[tmp].vis*=id;
        s[tmp].vis=s[tmp].vis%10007;
    }
    else
    {
        if(s[tmp].vis!=-1)
        {
            push(tmp);
        }
        int mid=(s[tmp].l+s[tmp].r)/2;
        if(ll>mid)
        {
            up2(ll,rr,tmp*2|1,id);
        }
        else if(rr<=mid)
        {
            up2(ll,rr,tmp*2,id);
        }
        else
        {
            up2(ll,mid,tmp*2,id);
            up2(mid+1,rr,tmp*2|1,id);
        }
    }
}
void up3(int ll,int rr,int tmp,long long id)
{
    if(s[tmp].l==ll&&s[tmp].r==rr)
    {
        s[tmp].vis=id;
        s[tmp].vis=s[tmp].vis%10007;
    }
    else
    {
        if(s[tmp].vis!=-1)
        {
            push(tmp);
        }
        int mid=(s[tmp].l+s[tmp].r)/2;
        if(ll>mid)
        {
            up3(ll,rr,tmp*2|1,id);
        }
        else if(rr<=mid)
        {
            up3(ll,rr,tmp*2,id);
        }
        else
        {
            up3(ll,mid,tmp*2,id);
            up3(mid+1,rr,tmp*2|1,id);
        }
    }
}
int q(int ll,int rr,int tmp,long long f)
{
    int i;
    long long w;
    if(s[tmp].vis!=-1)
    {
        w=1;
        for(i=0; i<f; i++)
        {
            w*=s[tmp].vis;
        }
        return (w*(rr-ll+1))%10007;
    }
    else
    {
        int mid=(s[tmp].l+s[tmp].r)/2;
        if(rr<=mid)
        {
            return q(ll,rr,tmp*2,f)%10007;
        }
        else if(ll>mid)
        {
            return q(ll,rr,tmp*2|1,f)%10007;
        }
        else
        {
            return (q(ll,mid,tmp*2,f)+q(mid+1,rr,tmp*2|1,f))%10007;
        }
    }
}
int main()
{
    int i,ans;
    while(1)
    {
        RD(n);
        RD(m);
        if(n==0&&m==0)
        {
            return 0;
        }
        build(1,n,1);
        s[1].vis=0;
        for(i=0; i<m; i++)
        {
            RD(c);
            RD(x);
            RD(y);
            scanf("%lld",&p);
            if(c==1)
            {
                up1(x,y,1,p);
            }
            else if(c==2)
            {
                up2(x,y,1,p);
            }
            else if(c==3)
            {
                up3(x,y,1,p);
            }
            else if(c==4)
            {
                ans=q(x,y,1,p);
                OT(ans);
                printf("\n");
            }
        }
    }
    return 0;
}

1009 Building bridges

水题不多说,暴力直接搜

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
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');
}
char a[41][41];
int main()
{
    int i,j,m,n,xx,yy,x,y,l,k,rr,ll,M,MM;
    while(1)
    {
        RD(m);
        RD(n);
        if(m==0&&n==0)
        {
            break;
        }
        for(i=0; i<m; ++i)
        {
            for(j=0; j<n; ++j)
            {
                scanf("%c",&a[i][j]);
            }
            getchar();
        }
        MM=10000;
        for(i=0; i<m; ++i)
        {
            for(j=0; j<n; ++j)
            {
                if(a[i][j]=='H')
                {
                    M=10000;
                    for(l=0; l<m; ++l)
                    {
                        for(k=0; k<n; ++k)
                        {
                            if(a[l][k]=='C')
                            {
                                if(abs(i-l)+abs(j-k)<M)
                                {
                                    M=abs(i-l)+abs(j-k);
                                    x=l;
                                    y=k;
                                }
                            }
                        }
                    }
                    if(M<MM)
                    {
                        MM=M;
                        xx=x;
                        yy=y;
                        rr=i;
                        ll=j;
                    }
                }
            }
        }
        printf("%d %d% d% d\n",rr,ll,xx,yy);
    }
    return 0;
}


1010 Shaolin

Splay树,模板题,直接套用Kong神的模板,1A不解释了。。。

Kong神BLOG:传送门

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
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
{
    int x,y;
} ax[111111];
int ch[111111][2],num[111111],fa[111111],data[1111111];
int root,tot;
void rotate(int x,int kind)
{
    int y=fa[x];
    ch[y][!kind]=ch[x][kind];
    fa[ch[x][kind]]=y;
    if(fa[y])
    {
        ch[fa[y]][ch[fa[y]][1]==y]=x;
    }
    fa[x]=fa[y];
    ch[x][kind]=y;
    fa[y]=x;
}
void Splay(int x,int s)
{
    int z,y,kind;
    while(fa[x]!=s)
    {
        if(fa[fa[x]]==s)
        {
            rotate(x,ch[fa[x]][0]==x);
        }
        else
        {
            y=fa[x];
            z=fa[y];
            kind=(ch[z][0]==y);
            if(ch[y][kind]==x)
            {
                rotate(x,!kind);
                rotate(x,kind);
            }
            else
            {
                rotate(y,kind);
                rotate(x,kind);
            }
        }
    }
    if(s==0)
    {
        root=x;
    }
}
void newNode(int& x,int k,int father)
{
    x=++tot;
    ch[x][0]=ch[x][1]=0;
    data[x]=k;
    fa[x]=father;
}
int insert(int k)
{
    int r=root;
    while(ch[r][data[r]<k])
    {
        if(data[r]==k)
        {
            Splay(r ,0);
            return 0;
        }
        r=ch[r][data[r]<k];
    }
    newNode(ch[r][data[r]<k],k,r);
    Splay(ch[r][data[r]<k],0);
    return 1;
}
int get_pree(int k)
{
    int d=ch[k][0];
    if(d==0)
    {
        return -1;
    }
    while(ch[d][1])
    {
        d=ch[d][1];
    }
    return d;
}
int get_next(int k)
{
    int d=ch[k][1] ;
    if(d==0)
    {
        return -1;
    }
    while(ch[d][0])
    {
        d=ch[d][0];
    }
    return d;
}
int main()
{
    int n,i,a1,a2;
    while(1)
    {
        RD(n);
        if(n==0)
        {
            break;
        }
        root=tot=0;
        for(i=1; i<=n; i++)
        {
            RD(ax[i].x);
            RD(ax[i].y);
            if(i==1)
            {
                printf("%d %d\n",ax[i].x,1);
                newNode(root,ax[i].y,0);
                continue ;
            }
            if(insert(ax[i].y)==0)
            {
                continue;
            }
            a1=get_next(root);
            a2=get_pree(root);
            if(a1==-1)
            {
                printf("%d %d\n",ax[i].x,ax[a2].x);
            }
            else if(a2==-1)
            {
                printf("%d %d\n",ax[i].x,ax[a1].x);
            }
            else
            {
                if(abs(data[a1]-data[root])<abs(data[root]-data[a2]))
                {
                    printf("%d %d\n",ax[i].x,ax[a1].x);
                }
                else if(abs(data[a1]-data[root])>abs(data[root]-data[a2]))
                {
                    printf("%d %d\n",ax[i].x,ax[a2].x);
                }
                else
                {
                    if(data[a1]<data[a2])
                    {
                        printf("%d %d\n",ax[i].x,ax[a1].x);
                    }
                    else
                    {
                        printf("%d %d\n",ax[i].x,ax[a2].x);
                    }
                }
            }
        }
    }
    return 0 ;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值