題目鏈接: /
題目
奶牛們爲什麼要穿馬路?一個原因只是因爲的牧場的路實在是太多了,使得奶牛們每天不得不穿梭在許許多多的馬路中央
的牧場可以看作是一塊 的田地, 條南北向的道路和 條東西向的道路貫穿整個牧場,同時是每塊田野的分界線。牧場的最外面是一圈高大的柵欄以防止奶牛離開牧場。只要穿過分離兩塊田野的道路,就可以從任何田野移動到與其相鄰的田野裏去(北,東,南或西)。當然,穿過每一條馬路都是需要TT 時間的。
有一天,邀請來他家下棋,從牧場的西北角出發,的家在牧場的東南角。因爲在中途可能會餓,所以她每走過三塊田野就要停下來,享用她所在田野上的新鮮的牧草(不包括的出發點,但是可能會包括終點的家),牧場上有些田野的牧草長得比其他地方茂盛,所以對應的停留時間也會變長。
請幫幫計算出她走到家的最短時間。
輸入
接下來 行,每行 個數表示每塊田野需要停留的時間(每塊最多不超過),第一行的第一塊田野是牧場的西北角
輸出
一行一個整數表示走到家的最短時間
樣例輸入
4 2
30 92 36 10
38 85 60 16
41 13 5 68
20 97 13 80
樣例輸出
31
樣例解釋
對於樣例,先向東走過了三塊田野(在停留),再向南走兩步,又向西走了一步(在停留),最後向南走一步,再向東走一步到達的家(不用停留),總共時間是(停留時間)+(穿馬路時間)=
思路
這道題其實就是一道最短路。
因爲題目說每走部就要喫草,那我們就讓它三步三步的走,把從一個點走三步可以走到的地方連起來就完事了。
但是,都最後的時候不一定走了三步,有可能最後只走了一兩步就走到了,這樣就不用喫草,只用加上走路的時間,那到最後一步的時候我們就判斷一下從哪裏走到終點最省時間,就可以了。
具體看代碼吧。
代碼
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
struct node {
int x, y;
};
int n, t, a[101][101], dis[101][101], ans;
bool in[101][101];
int dx[16] = {0, 0, 3, -3, 1, 1, 2, 2, -1, -1, -2, -2, 0, 0, 1, -1};
int dy[16] = {3, -3, 0, 0, 2, -2, 1, -1, 2, -2, 1, -1, 1, -1, 0, 0};
bool ch(int x, int y) {
if (x < 1 || y < 1 || x > n || y > n) return 0;
return 1;
}
void spfa(int x, int y) {//最短路
queue<node>q;
q.push((node){x, y});
memset(dis, 0x7f, sizeof(dis));
dis[x][y] = 0;
in[x][y] = 1;
while (!q.empty()) {
node now = q.front();
q.pop();
in[now.x][now.y] = 0;
for (int i = 0; i < 16; i++) {
int tx = now.x + dx[i], ty = now.y + dy[i];
if (ch(tx, ty) && dis[now.x][now.y] + a[tx][ty] + 3 * t < dis[tx][ty]) {//記得要加上走路的時間
dis[tx][ty] = dis[now.x][now.y] + a[tx][ty] + 3 * t;
if (!in[tx][ty]) {
in[tx][ty] = 1;
q.push((node){tx, ty});
}
}
}
}
}
int main() {
// freopen("visitfj.in", "r", stdin);
// freopen("visitfj.out", "w", stdout);
scanf("%d %d", &n, &t);//讀入
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
scanf("%d", &a[i][j]);//讀入
spfa(1, 1);//最短路
ans = min(dis[n][n], dis[n - 1][n] + t);//租後一步是怎麼走到終點的(指不用喫草的時候)
ans = min(ans, dis[n][n - 1] + t);
ans = min(ans, dis[n - 2][n] + t * 2);
ans = min(ans, dis[n][n - 2] + t * 2);
ans = min(ans, dis[n - 1][n - 1] + t * 2);
printf("%d", ans);//輸出
// fclose(stdin);
// fclose(stdout);
return 0;
}