1. 程式人生 > >2013 ACM-ICPC杭州賽區全國邀請賽——題目重現

2013 ACM-ICPC杭州賽區全國邀請賽——題目重現

今天的比賽讓我又回憶起了長沙被虐的那次。。。感覺比長沙那次做起來相對輕鬆不少。。。

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 ;
}


相關推薦

2013 ACM-ICPC杭州賽區全國邀請賽——題目重現

今天的比賽讓我又回憶起了長沙被虐的那次。。。感覺比長沙那次做起來相對輕鬆不少。。。 1001 Robot  一道概率題,總共只有m*n的複雜度,每次遍歷1~n的位置上的概率分佈,再得到相應的下一位的概率,最後只要將l~r區間內的概率相加即可,直接陣列可能會MLE,建議使用滾

2013 ACM-ICPC南京賽區全國邀請賽——題目重現

In the year 3013, it has been 1000 years since the previous predicted rapture. However, the Maya will not play a joke any more and the Rapture finally com

2013 ACM-ICPC吉林通化全國邀請賽(hdu 4493

D-City Problem Description Luxer is a really bad guy. He destroys everything he met. One day Luxer went to D-city. D-city has N

2013 ACM-ICPC吉林通化全國邀請賽 && HDU 4499 Cannon (搜尋)

Cannon Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) Total Submis

2013ACM-ICPC杭州賽區全國邀請賽——Random Walk

題目連結 題意: n個點,按照題中給的公式可以求出任意兩個點轉移的概率。求從1到n的期望轉移次數分析: 設dp[i]為從i到n的期望,那麼可以得到公式dp[i] = sigma(dp[i + j]

2013 ACM-ICPC吉林通化全國邀請賽 && HDU 4597 Play Game (博弈 + 區間dp)

Play Game Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 1185 Accepted Submission(

2013 ACM/ICPC 長沙賽區湖大全國邀請賽 A題(6.1修訂)

小記:這次大賽教訓慘重,ACM的路任重道遠,現在努力做出每道題的解題報告吧。以此來撫慰我那慘痛的心靈。 題目: 這個題目名叫So easy!  當初看了 就想A, 現在看來這估計就是個陷阱,數學不好的必被坑。 由於我是用word寫好的,但是裡面的數學符號複製不出來,

2013 ACM-ICPC南京全國邀請賽

Count The Carries One day, Implus gets interested in binary addition and binary carry. He will transfer all decimal digits to binary dig

ACM-ICPC北京賽區2017網路同步賽 題目5 : Cats and Fish【模擬】

時間限制:1000ms 單點時限:1000ms 記憶體限制:256MB 描述 There are many homeless cats in PKU campus. They are all happy because the students in

ACM-ICPC北京賽區2017網路同步賽 題目6 : Secret Poems

題目6 : Secret Poems 時間限制:1000ms 單點時限:1000ms 記憶體限制:256MB 描述 The Yongzheng Emperor (13 December 1678 – 8 October 173

ACM-ICPC北京賽區(2017)網絡賽1【模擬+枚舉+數組操作】

fine enter who bit some title head efi cat 題目1 : Visiting Peking University 時間限制:1000ms 單點時限:1000ms 內存限制:256MB 描述 Ming

2017 ACM/ICPC 新疆賽區 I 題 A Possible Tree 帶權並查集

沒有 cpc ant tar tin 傳送門 表示 每天 blank 傳送門 題意:給定一棵帶權樹的形態, 但是並不知道每天條邊的具體權重. 然後給m個信息, 信息格式為u v val, 表示在樹上u 到 v 的路徑上經過的邊的權重的異或和為val, 問前面最多有多少個

hihoCoder-1633 ACM-ICPC北京賽區2017 G.Liaoning Ship’s Voyage 線段與三角形規範相交

dcm problem ems can 方向 class oss acm-icpc 相交 題面 題意:給你一個20*20的地圖,起點(0,0),終點(n-1,n-1),有障礙的點為‘#’,每次可以向8個方向走一步,還給了一個三角形,除了障礙以外,到

2016年ACM/ICPC大連賽區 D題(LCM性質+解一元二次方程)

題目連結:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5748 題意: 給你兩個數a,b,讓你拆成x

2016年ACM/ICPC北京賽區 E題(bfs)

題目連結:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5694 題意:一個長度為5的串,初始為12

2016年ACM/ICPC北京賽區 C題(有源匯有上下界的最小費用最大流)

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5692 題意:給你一個n*n(n<=50)的棋

2016年ACM/ICPC大連賽區 C題(JAVA高精度求sqrt(5)+威佐夫博弈)

題目連結:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5747 題意:除了資料範圍為10^100次方以外

2016年ACM/ICPC青島賽區 D題(數學推導)

題目連結:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5759 題意:給你n(n<=10)種硬幣,

2016年ACM/ICPC青島賽區 G題(費用流)

題目連結:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5762 題意: n(n<=200

2016年ACM/ICPC北京賽區 I題(思維 二項式展開)

題目連結:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5698 題意:給你一個只由0~9字元構成的長度為