上一集说道,我们可爱的[超无聊]解开了题目,然后我们的拯救世界六人组+小Home_W在感受万有引力的魅力
“啊啊啊啊”
5个分钟后
“啊啊啊”
10分钟后
巨巨们:
20分钟后:
大Home_W:“咋还没到底啊”
n个分钟后:
巨巨们终于到了底(不要问编剧为什么落了那么久他们落地没死)
他们站在一个门前,门上写着一串数字,就是这样子的:
赛文斯:“这啥意思啊”
首席军师布莱克:“第一行应该是指接下来n*m个数字吧,感觉像矩阵,3行行四列的矩阵”
小A:“应该是”
“怎么肥死,体验卡是啥东西?”,小明看着手上的纸
众人也都发现了自己手上居然有2张体验卡,同时还有一个答案板
“都没有题目的,这是要让我们猜题意吗?2张体验卡,体验一下”
布莱克:“我猜题意贼六的,冲冲冲”,只见布莱克随便在答案版上面写了个一个数字“13”,就冲了上去
只听一阵“啊啊啊”,1分钟后,布莱克变成了一道光,又回到了原地
布莱克一脸生无可恋的:“wsl,tsl,我测出来了,而且每个房间都要一个怪兽,那个怪兽会砍我,wsl,真疼,1 1是我们的起点,3 4是终点”
布莱克摸了摸自己的脑袋继续说:“如果我没猜错的话,题意应该就是n*m个房间,然后每个房间的怪兽都要一定的伤害,然后必须从起点走到终点,剩下的就不知道了,答案版写的啥我就不动了”
大Home_W:“你再进去试试,让怪砍你,你答案版会扣血不”
布莱克都快哭了:“哥啊,别啊,会死人的”
大Home_W直接一脚把他踢进去:“你不是说你猜题目很牛吗,快滚进去”
又一阵“啊啊啊”
一道光闪过,布莱克:“是的,会扣”
大Home_W:“剩下的就是答案的意义了”,大Home_W一脸微笑的看向了赛文斯
赛文斯:“哥你别踢,我自己上”,赛文斯赶紧向自己的板上写上了自己的幸运数字7,
没有惨叫,一道光闪过,“咦,不疼啊,怎么肥死布莱克,你疼nm呢”,赛文斯一脸惊喜的说道
大Home_W:“那答案应该就是7了,咦,数字居然变了”,大Home_W再次一脸微笑的看向了赛文斯
赛文斯一脸悲壮的,再次为了革命献上了自己的命(划掉)体验卡
10分钟后,
小A再一道光后,出现在了原地,“懂了,题意应该就是,n*m个房间,每个房间都会有四个门通往相邻的房间,每个房间内会有怪物造成一定的伤害,但是只要不被秒杀(伤害值大于等于血量),那么就可以补满生命。从给定的起点出发,到达指定的终点。
问最少需要多少血量才能通过这个副本。
”
小A一顿操作,立刻写出了,然后带着众人走向了下一集
单组数据。
第一行两个正整数 n 和 m。
第2 到 n + 1 行,每行 m个非负整数,代表房间内怪物的伤害。
第n + 2 两个整数x1和y1,表示起点坐标在第x1行第y1列。
第n + 3 两个整数x2和y2,表示终点坐标在第x2行第y2列。
行列号从1开始。
数据范围:
(0 < n,m < 1000 )
伤害最大不超过1000
输出一个整数,表示通过这个副本最少需要的血量。
3 4 1 2 5 4 5 6 7 8 9 4 5 3 1 1 3 4
7
【思路】:我的想法是每个点往右边和下面的点连接一条边,边权为两点间的最大值。
然后跑一下kruskal算法,判断起点终点的联通性,联通输出边权就是答案了。
附上代码
#include <bits/stdc++.h> #pragma GCC optimize(2) using namespace std; inline void Read(int &x) { char c=getchar(); x=0; while (c<'0'||c>'9') { c=getchar(); } while (c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); } } inline void Out(int a) //输出一个整型 { if(a<0) { putchar('-'); a=-a; } if(a>9) Out(a/10); putchar(a%10+'0'); } const int MAXM = 2e6 + 5; const int MAXN = 1005; int arr[MAXN][MAXN]; struct node{ int be, en; int value; }brr[MAXM]; int n, m; int pre[MAXN * MAXN + 5]; bool cmp(node a,node b){ return a.value < b.value; } void Init(){ for(int i = 0; i < MAXN * MAXN + 5; i ++){ pre[i] = i; } } int acfinds(int x){ return x == pre[x] ? x : pre[x] = acfinds(pre[x]); } int kruskal(int b, int e, int len){ for(int i = 0; i < len; i ++){ if(acfinds(brr[i].be) != acfinds(brr[i].en)){ int x = acfinds(brr[i].be); int y = acfinds(brr[i].en); if(x < y){ pre[x] = y; } else{ pre[y] = x; } } if(acfinds(b) == acfinds(e)){ return brr[i].value + 1; } } return 0; } int main(){ Read(n); Read(m); Init(); for(int i = 1; i <= n; i ++) for(int j = 1; j <= m; j ++) Read(arr[i][j]); int num = 0; for(int i = 1; i <= n; i ++){ for(int j = 1; j <= m; j ++){ int x, y; x = i + 1, y = j; int value; if(x > 0 && x <= n){ value = max(arr[i][j], arr[x][y]); brr[num].be = m * (i - 1) + j; brr[num].en = m * (x - 1) + y; brr[num].value = value; num ++; } x = i, y = j + 1; if(y > 0 && y <= m){ value = max(arr[i][j], arr[x][y]); brr[num].be = m * (i - 1) + j; brr[num].en = m * (x - 1) + y; brr[num].value = value; num ++; } } } sort(brr, brr + num, cmp); int x1, y1, x2, y2; Read(x1); Read(y1); Read(x2); Read(y2); int begins = (x1-1) * m + y1; int ends = (x2-1) * m + y2; if(begins==ends) { Out(arr[x1][y1] + 1); printf(" "); } else { int result = kruskal(begins, ends, num); Out(result); printf(" "); } return 0; }