• NOIP模拟测试18「引子·可爱宝贝精灵·相互再归的鹅妈妈」


    待补

    引子

    题解

    大模拟,注意细节

    代码1

    #include<bits/stdc++.h>
    using namespace std;
    int n,m;char a[1005][1005];bool vst[1005][1005];
    void solve(int na,int nb)
    {
        int i=na,j=nb,now=0;
        while(1){
            j++;if(a[na][j]=='+')break;
        }
        while(1){
            i++;if(a[i][nb]=='+')break;
        }
        for(int k=na+1;k<i;k++){
            for(int l=nb+1;l<j;l++)if(a[k][l]>='0'&&a[k][l]<='9')now=now*10+a[k][l]-'0';
            if(now)break;
        }
        for(int k=i;k>=na;k--){
            if(j<=m&&a[k][j+1]=='-'){
                int ni=k,nj=j+1;vst[ni][nj]=1;
                while(1){
                    while(1){
                        if((a[ni][nj+1]=='-'||a[ni][nj+1]=='+')&&!vst[ni][nj+1])nj++;
                        else nj--;vst[ni][nj]=1;
                        if(a[ni][nj]=='+')break;
                    }
                    while(1){
                        ni++;vst[ni][nj]=1;
                        if(a[ni][nj]=='+'||a[ni][nj]=='-')break;
                    }
                    if(a[ni][nj]=='-')break;
                }
                while(a[ni][nj]!='+')nj--;solve(ni,nj);
            }
            else if(nb&&a[k][nb-1]=='-'){
                int ni=k,nj=nb-1;
                vst[ni][nj]=1;
                while(1){
                    while(1){
                        if((a[ni][nj+1]=='-'||a[ni][nj+1]=='+')&&!vst[ni][nj+1])nj++;
                        else nj--;vst[ni][nj]=1;
                        if(a[ni][nj]=='+')break;
                    }
                    while(1){
                        ni++;vst[ni][nj]=1;
                        if(a[ni][nj]=='+'||a[ni][nj]=='-')break;
                    }
                    if(a[ni][nj]=='-')break;
                }
                while(a[ni][nj]!='+')nj--;
                solve(ni,nj);
            }
        }
        printf("%d
    ",now);
    }
    int main()
    {
        bool fir=0;
        int sta,stb;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++){
                char c=getchar();
                while(c!='+'&&c!='|'&&c!='-'&&c!='.'&&(c>'9'||c<'0'))c=getchar();
                a[i][j]=c;
                if(a[i][j]=='+'&&!fir)sta=i,stb=j,fir=1;
            }
        solve(sta,stb);
        return 0;
    }

    代码2

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define A 1111
    char ch[A][A];
    ll n,m,top=0;
    ll h[A][A],stax[A],stay[A],low[A],len[A],sta[A];
    ll chuanx,chuany;
    bool vis[A][A];
    struct node {
        ll hang,id;
        friend bool operator < (const node &a,const node &b){
            return a.hang<b.hang;
        }
    };
    priority_queue <node> high[A];
    const ll nowx[5]={0,1,-1,0,0};
    const ll nowy[5]={0,0,0,1,-1};
    //1右0左2下
    void pre(ll x,ll y,ll fx){
        
        if(h[x][y]){
    //        printf("x=%lld y=%lld h=%lld fx=%lld
    ",x,y,h[x][y],fx);
            chuanx=x,chuany=y;
            return ;
        }
        if(ch[x][y]=='+'){
            if(fx==0||fx==1){
                pre(x+1,y,2);
            }
            if(fx==2){
                if(ch[x][y+1]=='-')
                    pre(x,y+1,1);
                if(ch[x][y-1]=='-')
                    pre(x,y-1,0);
            }
        }
        else{
            if(fx==1&&y+1<=m)
                pre(x,y+1,1);
            if(fx==0&&y-1>=1)
                pre(x,y-1,0);
            if(fx==2&&x+1<=n)
                pre(x+1,y,2);
        }
    }
    void dfs(ll num){
        while(!high[num].empty()){
            ll x=high[num].top().id;
    //        printf("hang=%lld
    ",high[num].top().hang);
            high[num].pop();
            dfs(x);
        }
        low[++low[0]]=num;
    }
    void del(ll x,ll y,ll num){
        top=1;
    //    printf("num=%lld
    ",num);
        stax[top]=x,stay[top]=y;
        while(top){
            ll x=stax[top],y=stay[top];
            h[x][y]=num;
            top--;
            for(ll i=1;i<=4;i++){
                ll x2=x+nowx[i],y2=y+nowy[i];
                h[x2][y2]=num;
    //            printf("x2=%lld y2=%lld
    ",x2,y2);
                if((ch[x2][y2]=='.'||isdigit(ch[x2][y2]))&&!vis[x2][y2]){
                    top++;
                    stax[top]=x2,stay[top]=y2;
                    vis[x2][y2]=1;
                }
            }
        }
    //    printf("*********************%lld
    ",h[14][61]);
    }
    void bfs(){
        for(ll i=1;i<=n;i++)
            for(ll j=1;j<=m;j++){
                if(isdigit(ch[i][j])){
    //                printf("ch[%lld][%lld]=%d
    ",i,j,ch[i][j]-'0');
                    ll x=ch[i][j]-'0';
                    for(ll w=j+1;w<=m;w++){
                        if(isdigit(ch[i][w]))
                            x=x*10+ch[i][w]-'0';
                        else break;
                    }
    //                printf("x1=%lld x2=%lld x3=%lld
    ",x,x2,x3);
                    if(!vis[i][j])del(i,j,x);
                }
            }
    /*    for(ll i=1;i<=n;i++,puts(""))
            for(ll j=1;j<=m;j++){
                printf("%lld",h[i][j]);
            }
    */    for(ll i=1;i<=n;i++)
            for(ll j=1;j<=m;j++){
                if(ch[i][j]=='|'){
                    if(ch[i][j+1]=='-'){
                        pre(i,j+1,1);
                        node no;
    //                    printf("i=%lld j=%lld h=%lld chan=%lld %lld h=%lld
    ",i,j,h[i][j],chuanx,chuany,h[chuanx][chuany]);
                        no.hang=i,no.id=h[chuanx][chuany];
                        high[h[i][j]].push(no);
                    }
                    if(ch[i][j-1]=='-'){
                        pre(i,j-1,0);
                        node no;
    //                    printf("i=%lld j=%lld h=%lld chan=%lld %lld h=%lld
    ",i,j,h[i][j],chuanx,chuany,h[chuanx][chuany]);
                        no.hang=i,no.id=h[chuanx][chuany];
                        high[h[i][j]].push(no);
                    }
                }
            }
    
        dfs(1);
        for(ll i=1;i<=low[0];i++){
            printf("%lld
    ",low[i]);
        }
    }
    
    int main(){
    //    freopen("wos.txt","w",stdout);
        scanf("%lld%lld",&n,&m);
        for(ll i=1;i<=n;i++){
            scanf("%s",ch[i]+1);
        }
        bfs();
    }

    可爱宝贝精灵

    题解

    一个不错的dfs题(还能练习剪枝)

    一个不错的dp题

    思考dp数组含义

    首先我们知道我们到一个有小精灵地方就必须抓住它(显然)而不是来回逛几圈再次经过它再抓

    然后我们只要从一个方向走就必须抓住至少一只小精灵,转向之后也至少抓住一只精灵,(否则你走这一段就是没用的)

    $i,j$分别表示当前最左到$i$最右到$j$时的最大值

    设$f[i][j]$肯定不行时间难以确认,多一维表示时间$f[t][i][j]$也难以确定,然而你在左面还是右面依然难以确定

    那么再加一维$f[t][i][j][2]$中$[1]$表示在右面,$[0]$表示在左面

    转移很好转移,不像昨天那个傻逼t2式子

    类似离散化一下

    假如当前l,你可以走到r或者l-1

    假如当前r,你可以走到l或者r+1

    用式子表示就是

    从$r$走到$l+1$再走到$l$

    从$l$走到$r-1$再走到$r$

    $f[i][l][r][0]=max(f[max(i-dis(l,l+1),0)][l+1][r][0],f[max(i-dis(l,r),0)][l+1][r][1])+Val;$
    $f[i][l][r][1]=max(f[max(i-dis(r-1,r),0)][l][r-1][1],f[max(i-dis(l,r),0)][l][r-1][0])+Val;$

    注意一下初始化!

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define py printf("tys is sb
    ")
    #define A 2010
    ll f[A][118][118][2];
    struct pocky{
        ll pla,val,tim;
        friend bool operator < (const pocky &a, const pocky &b){
            return a.pla<b.pla;
        }
    }texas[A];
    ll dis(ll l,ll r){
        return abs(texas[r].pla-texas[l].pla);
    }
    ll n,k,m,mx,mid,ans;
    void debuger(ll x){
        for(ll i=1;i<=m;i++,puts(""))
            for(ll j=i+1;j<=m;j++){
                printf("f[%lld][%lld][%lld]=%lld %lld
     ",x,i,j,f[x][i][j][1],f[x][i][j][0]);
            }
    }
    int main(){
        scanf("%lld%lld%lld",&n,&k,&m);
        for(ll i=1;i<=m;i++){
            scanf("%lld%lld%lld",&texas[i].pla,&texas[i].val,&texas[i].tim);
            mx=max(mx,texas[i].tim);
        }
        memset(f,-0x3f,sizeof(f));
        m++;
        texas[m].pla=k,
        texas[m].val=0,
        texas[m].tim=mx;
        sort(texas+1,texas+m+1);
        for(ll i=1;i<=m;i++){
            if(texas[i].pla==k&&texas[i].val==0){
                mid=i;
                break;
            }
        }
        f[0][mid][mid][0]=0;
        f[0][mid][mid][1]=0;
    //    printf("mid=%lld 
    ",texas[mid].pla);
        for(ll i=mid-1;i>=1;i--){
            ll tim=texas[mid].pla-texas[i].pla;
    //        printf("tim=%lld i=%lld mid=%lld 
    ",tim,i,mid);
            f[tim][i][mid][0]=f[dis(mid,i+1)][i+1][mid][0]+((tim<texas[i].tim)?texas[i].val:0);
            ans=max(ans,f[tim][i][mid][0]);
        }
        for(ll i=mid+1;i<=m;i++){
            ll tim=texas[i].pla-texas[mid].pla;
            f[tim][mid][i][1]=f[dis(mid,i-1)][mid][i-1][1]+((tim<texas[i].tim)?texas[i].val:0);
            ans=max(ans,f[tim][mid][i][1]);
        }
    //    printf("ans=%lld
    ",ans);
        for(ll i=1;i<=mx;i++)
            for(ll l=1;l<=mid-1;l++)
                for(ll r=mid+1;r<=m;r++){
                    f[i][l][r][0]=max(f[max(i-dis(l,l+1),0ll)][l+1][r][0],f[max(i-dis(l,r),0ll)][l+1][r][1])+((i<texas[l].tim)?texas[l].val:0);
                    f[i][l][r][1]=max(f[max(i-dis(r-1,r),0ll)][l][r-1][1],f[max(i-dis(l,r),0ll)][l][r-1][0])+((i<texas[r].tim)?texas[r].val:0);
                    ans=max(ans,max(f[i][l][r][0],f[i][l][r][1]));
    //                printf("    f[%lld][%lld][%lld][0]=%lld [%lld][%lld][%lld][1]=%lld
    ",i,l,r,f[i][l][r][0],i,l,r,f[i][l][r][1]);
                }
        printf("%lld
    ",ans);
    }

     相互在归的鹅妈妈

    我已没有下降的余地
  • 相关阅读:
    困难4. 寻找两个正序数组的中位数
    6. Z 字形变换
    学习mysql176. 第二高的薪水
    竞赛6194. 最小 XOR
    中等856. 括号的分数
    竞赛6193. 沙漏的最大总和
    竞赛2430. 对字母串可执行的最大删除数
    困难927. 三等分
    困难1235. 规划兼职工作
    学习下mysql175. 组合两个表
  • 原文地址:https://www.cnblogs.com/znsbc-13/p/11340743.html
Copyright © 2020-2023  润新知