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\n",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\n",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\n",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\n",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\n",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\n",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\n",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\n",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\n",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\n",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\n",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\n")
#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\n ",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 \n",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 \n",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\n",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\n",i,l,r,f[i][l][r][0],i,l,r,f[i][l][r][1]);
            }
    printf("%lld\n",ans);
}

 相互在归的鹅妈妈

posted @ 2019-08-12 16:04  znsbc  阅读(221)  评论(0编辑  收藏  举报