1 条题解
-
0
自动搬运
来自洛谷,原作者为

温栀槿
**搬运于
2025-08-24 21:37:24,当前版本为作者最后更新于2018-11-03 07:23:02,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
首先,想的是3遍BFS直接求解。
但是发现前两问很好求解,但是如果到第三个问题怎么跑出来都比答案大,
因为一个点可能被增加路径后到它下一个点,之前的路径数会被重复统计。
所以f[ax][ay]+=f[x][y]应该改为f[ax][ay]++,这样就保证每次只会多出一条新的路径。
注意细节实现,同时bfs时开inq[]数组(我的ch[]数组)记录是否在队内。
如果不加,那每个点会被访问多次,导致2个点TLE。
代码
#include<bits/stdc++.h> using namespace std; #define ll long long #define mp make_pair const int N=35; ll dp[N][N],dis[N][N],f[N][N]; int n,m; int sum; int sx,sy,tx,ty; int vis[N][N]; int dx[10]={1,-1,2,-2,1,-1,2,-2},dy[10]={2,2,1,1,-2,-2,-1,-1}; bool fg=0,ch[N][N]; queue<pair<int,int> > q,q1,q2; void bfs(){ while(!q.empty()){ int x=q.front().first; int y=q.front().second; ch[x][y]=0; q.pop(); for(int i=0;i<=7;i++){ int ax=x+dx[i],ay=y+dy[i]; int sum=0; if(ax>n||ay>m) continue; if(ax<=0||ay<=0) continue; if(vis[ax][ay]==2) continue; if(dp[ax][ay]>dp[x][y]+vis[ax][ay]){ dp[ax][ay]=dp[x][y]+vis[ax][ay]; if(ax==tx&&ay==ty) continue; if(ch[ax][ay]) continue; q.push(mp(ax,ay)); ch[ax][ay]=1; } } } } void bfs2(){ while(!q1.empty()){ int x=q1.front().first; int y=q1.front().second; ch[x][y]=0; q1.pop(); for(int i=0;i<=7;i++){ int ax=x+dx[i],ay=y+dy[i]; int sum=0; if(ax>n||ay>m) continue; if(ax<=0||ay<=0) continue; if(vis[ax][ay]==2) continue; if(dp[ax][ay]!=dp[x][y]+vis[ax][ay]) continue; if(dis[x][y]+1>dis[ax][ay]) { continue; } dis[ax][ay]=dis[x][y]+1; if(ch[ax][ay]) continue; q1.push(mp(ax,ay)); ch[ax][ay]=1; // f[ax][ay]+=f[x][y]; } } } void bfs3(){ while(!q2.empty()){ int x=q2.front().first; int y=q2.front().second; ch[x][y]=0; q2.pop(); for(int i=0;i<=7;i++){ int ax=x+dx[i],ay=y+dy[i]; int sum=0; if(ax>n||ay>m) continue; if(ax<=0||ay<=0) continue; if(vis[ax][ay]==2) continue; if(dis[x][y]+1!=dis[ax][ay]) { continue; } if(dp[x][y]+vis[ax][ay]!=dp[ax][ay]) continue; // dis[ax][ay]=stp+1; f[ax][ay]+=f[x][y]; if(ax==tx&&ay==ty) continue; if(ch[ax][ay]) continue; q2.push(mp(ax,ay)); ch[ax][ay]=1; } } } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ int p; scanf("%d",&p); if(p==3) { sx=i,sy=j; vis[i][j]=0; } if(p==4){ tx=i,ty=j; vis[i][j]=0; } if(p==1) vis[i][j]=0; if(p==0) vis[i][j]=1; if(p==2) vis[i][j]=2; } } memset(dp,99,sizeof(dp)); memset(dis,99,sizeof(dis)); memset(ch,0,sizeof(ch)); // cout<<dp[1][1]; dp[sx][sy]=0; q.push(mp(sx,sy)); bfs(); if(dp[tx][ty]==dp[0][0]) { printf("-1\n"); return 0; } else printf("%lld\n",dp[tx][ty]); dis[sx][sy]=0; memset(ch,0,sizeof(ch)); q1.push(mp(sx,sy)); bfs2(); printf("%lld\n",dis[tx][ty]); f[sx][sy]=1; memset(ch,0,sizeof(ch)); q2.push(mp(sx,sy)); bfs3(); printf("%lld\n",f[tx][ty]); }第二种就是在一遍bfs种直接处理答案,
考虑如果荷花数更优,直接把(x,y)的信息给(ax,ay)
如果荷花数相同,但步数更优,同上
如果两个都相同,f[ax][ay]+=f[x][y](方案数)
代码:
#include<bits/stdc++.h> using namespace std; #define ll long long #define mp make_pair const int N=35; ll dp[N][N],dis[N][N],f[N][N]; int n,m; int sum; int sx,sy,tx,ty; int vis[N][N]; int dx[10]={1,-1,2,-2,1,-1,2,-2},dy[10]={2,2,1,1,-2,-2,-1,-1}; bool fg=0,ch[N][N]; queue<pair<int,int> > q; void bfs(int x,int y){ while(!q.empty()){ int x=q.front().first; int y=q.front().second; ch[x][y]=0; q.pop(); for(int i=0;i<=7;i++){ bool fg=0; int ax=x+dx[i],ay=y+dy[i]; int sum=0; if(ax>n||ay>m) continue; if(ax<=0||ay<=0) continue; if(vis[ax][ay]==2) continue; if(dp[ax][ay]>dp[x][y]+vis[ax][ay]){ dp[ax][ay]=dp[x][y]+vis[ax][ay]; dis[ax][ay]=dis[x][y]+1; f[ax][ay]=f[x][y]; if(ax==tx&&ay==ty) continue; fg=1; } else if(dp[ax][ay]==dp[x][y]+vis[ax][ay]&&dis[ax][ay]>dis[x][y]+1){ dp[ax][ay]=dp[x][y]+vis[ax][ay]; dis[ax][ay]=dis[x][y]+1; f[ax][ay]=f[x][y]; if(ax==tx&&ay==ty) continue; fg=1; } else if(dp[ax][ay]==dp[x][y]+vis[ax][ay]&&dis[ax][ay]==dis[x][y]+1){ f[ax][ay]+=f[x][y]; if(ax==tx&&ay==ty) continue; fg=1; } if(fg&&!ch[ax][ay]){ q.push(mp(ax,ay)); ch[ax][ay]=1; } } } } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ int p; scanf("%d",&p); if(p==3) { sx=i,sy=j; vis[i][j]=0; } if(p==4){ tx=i,ty=j; vis[i][j]=0; } if(p==1) vis[i][j]=0; if(p==0) vis[i][j]=1; if(p==2) vis[i][j]=2; } } memset(dp,99,sizeof(dp)); memset(dis,99,sizeof(dis)); // cout<<dp[1][1]; dp[sx][sy]=0; dis[sx][sy]=0; f[sx][sy]=1; q.push(mp(sx,sy)); ch[sx][sy]=1; bfs(sx,sy); if(dp[tx][ty]==dp[0][0]) { printf("-1\n"); return 0; } else printf("%lld\n",dp[tx][ty]); printf("%lld\n",dis[tx][ty]); printf("%lld\n",f[tx][ty]); }
- 1
信息
- ID
- 1440
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者