Why Did the Cow Cross the Road I G

Why Did the Cow Cross the Road I GWhy\ Did\ the\ Cow\ Cross\ the\ Road\ I\ G

題目鏈接:luogu P3659luogu\ P3659 / jzoj 6688jzoj\ 6688

題目

奶牛們爲什麼要穿馬路?一個原因只是因爲FJFJ的牧場的路實在是太多了,使得奶牛們每天不得不穿梭在許許多多的馬路中央

FJFJ的牧場可以看作是一塊 N×NN\times N 的田地3N100(3\le N\le 100)N1N-1 條南北向的道路和 N1N-1 條東西向的道路貫穿整個牧場,同時是每塊田野的分界線。牧場的最外面是一圈高大的柵欄以防止奶牛離開牧場。BessieBessie只要穿過分離兩塊田野的道路,就可以從任何田野移動到與其相鄰的田野裏去(北,東,南或西)。當然,BessieBessie穿過每一條馬路都是需要TT 時間的。0T1,000,000(0\le T\le 1,000,000)

有一天,FJFJ邀請BessieBessie來他家下棋,BessieBessie從牧場的西北角出發,FJFJ的家在牧場的東南角。因爲BessieBessie在中途可能會餓,所以她每走過三塊田野就要停下來,享用她所在田野上的新鮮的牧草(不包括BessieBessie的出發點,但是可能會包括終點FJFJ的家),牧場上有些田野的牧草長得比其他地方茂盛,所以BessieBessie對應的停留時間也會變長。

請幫幫BessieBessie計算出她走到FJFJ家的最短時間。

輸入

接下來 NN 行,每行 NN 個數表示每塊田野BessieBessie需要停留的時間(每塊最多不超過100,000100,000),第一行的第一塊田野是牧場的西北角

輸出

一行一個整數表示BessieBessie走到FJFJ家的最短時間

樣例輸入

4 2
30 92 36 10
38 85 60 16
41 13 5 68
20 97 13 80

樣例輸出

31

樣例解釋

對於樣例,BessieBessie先向東走過了三塊田野(在10“10”停留),再向南走兩步,又向西走了一步(在5“5”停留),最後向南走一步,再向東走一步到達FJFJ的家(不用停留),總共時間是1515(停留時間)+1616(穿馬路時間)=3131

思路

這道題其實就是一道最短路。

因爲題目說每走33部就要喫草,那我們就讓它三步三步的走,把從一個點走三步可以走到的地方連起來就完事了。
但是,都最後的時候不一定走了三步,有可能最後只走了一兩步就走到了,這樣就不用喫草,只用加上走路的時間,那到最後一步的時候我們就判斷一下從哪裏走到終點最省時間,就可以了。

具體看代碼吧。

代碼

#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;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章