待补
引子
题解
大模拟,注意细节
代码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); }
相互在归的鹅妈妈