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