分析一下题目,我们要抓住重点
但是有细节需要处理,就是我们的vis要什么时候标记
注意我们这题的代码是
vis[1][1][a[1][1]] = 1;
while(q.size()){
auto t = q.front();
int x = t[0],y=t[1],z=t[2];
q.pop();//别忘记了
//vis[x][y][z] = 1;//标记为访问过
if(vis[x][y][z]) continue;
vis[x][y][z] = 1;
for(int i=0;i<=3;i++){
int xx = x+addx[i],yy = y+addy[i];
if(xx<1||xx>n||yy<1||yy>m) continue; // 越界
int d =( z + a[xx][yy]) % mo;
if(vis[xx][yy][d]) continue;
vis[xx][yy][d] = 1;
dis[xx][yy][d] = dis[x][y][z] + 1;
q.push({xx,yy,d});
}
}
不能一进来再标记,因为我们已经确定我们每一次找到答案的的时候就已经是最优解了,如果我们在pop的时候再进行标记,会让我们的代码复杂度太高,时间爆炸。
这一题要区分狄克斯特拉算法,附上代码
int dikj() {
priority_queue<pair<int, int>> q;
int ma = 0;
//vis[start] = 1; // 记录一下 不用写
for (int i = 0; i <= n; i++) vis[i] = 0,di[i] = 0xffffff;
//vis[start] = 1;
q.push({ 0,start });
while (q.size()) {
int dis = -q.top().first, node = q.top().second;
q.pop();
if (vis[node]) continue; //一取出来就要判断
vis[node] = 1;
for (int i = h[node]; i != -1; i = ne[i]) {
int to = e[i];
//if (vis[to]) continue; // 不是在这里判断
//vis[to] = 1;
int newdis = energy[i] + dis; // 这是新的距离
if (newdis < di[to]) {
di[to] = newdis;
q.push({ -newdis, to });
}
/* ma = max(ma, newdis);*/
}
}
for (int i = 1; i <= n; i++) {
if (di[i] == 0xffffff) continue;
ma = max(ma, di[i]);
}
return ma;
}
狄克斯特拉算法中我们用的是priorityqueue,所以我们的queue中可能有多个同一节点,我们只有取出来的时候才是最优解
ac代码如下:
#include<bits/stdc++.h>
using namespace std;
int n,m,p;
const int N = 15;
const int M = (int)1e4+2;
int mo;
int a[N][N],b;
int dis[N][N][M]; // 记录到达 i , j 且 Mod k 的最短时间
int vis[N][N][M]; // 用来记录是否走过
int addx[] = {-1,0,0,1};
int addy[] = {0,-1,1,0};
int bfs(){
queue<array<int,3>> q;
q.push({1,1,a[1][1]}); // 反正是bfs,直接就用queue就好了
vis[1][1][a[1][1]] = 1;
while(q.size()){
auto t = q.front();
int x = t[0],y=t[1],z=t[2];
q.pop();//别忘记了
//vis[x][y][z] = 1;//标记为访问过
for(int i=0;i<=3;i++){
int xx = x+addx[i],yy = y+addy[i];
if(xx<1||xx>n||yy<1||yy>m) continue; // 越界
int d =( z + a[xx][yy]) % mo;
if(vis[xx][yy][d]) continue;
//int d =( z + a[xx][yy]) % mo;
vis[xx][yy][d] = 1;
dis[xx][yy][d] = dis[x][y][z] + 1;
//if(xx==n&&yy==m&&d==0) return dis[xx][yy][d];
q.push({xx,yy,d});
}
}
if(dis[n][m][0]) return dis[n][m][0];
return -1;
}
int main(){
cin >> n >> m >> p;
mo = p-1;
if(p==2){
cout<<n+m-2<<endl;
return 0;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin >> a[i][j];
a[i][j] %= mo;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin >> b;
}
}
cout << bfs();
return 0;
}