从大厂辞职,上岸事业编的6个月,我emo了。收入砍了一半,生活的扣扣嗖嗖,原来上岸只是一座围城,我站在城里不知所措
刚看到个贴子,说有网友从大厂辞职上岸事业编,六个月就emo了。收入砍半,日子过得紧巴巴,感叹“原来上岸只是座围城”。这话太真实了。
不是编制不好,而是每个人想要的生活不同。大厂拼的是钱和机会,体力换自由;体制内拼的是稳定和节奏,时间换安全感。问题是,很多人上岸前以为进了天堂,结果发现是个慢节奏的牢笼。
网友们的回复我也看了,有的劝她“知足常乐”,有的说“劝人上岸,天打雷劈”。其实都没错,只是位置不同。你拿高薪就得受折磨,拿稳定就得忍枯燥,鱼和熊掌确实不能兼得。
算法题:倒水
两个水壶,容量分别是 x 和 y,要量出恰好 t 升水。操作就那几样:装满、倒空、互相倒,直到其中一个壶里出现 t。约束别忘了,t ≤ max(x,y),而且 t 必须是 gcd(x,y) 的倍数,不然干啥都白搭。
这玩意最稳的是把每个“状态”当图里的点,状态=(A壶当前量,B壶当前量)。从(0,0)出发,用 BFS 一层层扩散。六种操作产生邻居:装满A、装满B、倒空A、倒空B、A→B、B→A。第一次遇到“某壶==t”就是最短步数,还能顺带回溯打印步骤。为啥是最短?因为 BFS 天然按步数层层推进。
Java 代码
import java.util.*;
publicclassWaterJugBFS{
staticclassNode{
int a, b; // 当前两壶水量
Node prev; // 上一步
String op; // 到达本步的操作描述
Node(int a, int b, Node prev, String op) {
this.a = a; this.b = b; this.prev = prev; this.op = op;
}
}
publicstatic List<String> solve(int X, int Y, int T){
if (T == 0) return List.of("啥也不干:已得到 0");
if (T > Math.max(X, Y) || T % gcd(X, Y) != 0) return List.of("无解");
boolean[][] vis = newboolean[X + 1][Y + 1];
Queue<Node> q = new ArrayDeque<>();
Node start = new Node(0, 0, null, "开始 (0,0)");
q.add(start); vis[0][0] = true;
while (!q.isEmpty()) {
Node cur = q.poll();
if (cur.a == T || cur.b == T) return buildPath(cur);
for (Node nxt : expand(cur, X, Y)) {
if (!vis[nxt.a][nxt.b]) {
vis[nxt.a][nxt.b] = true;
q.add(nxt);
}
}
}
return List.of("无解");
}
static List<Node> expand(Node n, int X, int Y){
List<Node> list = new ArrayList<>(6);
// 1) 装满A
list.add(new Node(X, n.b, n, "装满A -> (" + X + "," + n.b + ")"));
// 2) 装满B
list.add(new Node(n.a, Y, n, "装满B -> (" + n.a + "," + Y + ")"));
// 3) 倒空A
list.add(new Node(0, n.b, n, "倒空A -> (0," + n.b + ")"));
// 4) 倒空B
list.add(new Node(n.a, 0, n, "倒空B -> (" + n.a + ",0)"));
// 5) A -> B
int moveAB = Math.min(n.a, Y - n.b);
list.add(new Node(n.a - moveAB, n.b + moveAB, n,
"A->B " + moveAB + " -> (" + (n.a - moveAB) + "," + (n.b + moveAB) + ")"));
// 6) B -> A
int moveBA = Math.min(n.b, X - n.a);
list.add(new Node(n.a + moveBA, n.b - moveBA, n,
"B->A " + moveBA + " -> (" + (n.a + moveBA) + "," + (n.b - moveBA) + ")"));
return list;
}
static List<String> buildPath(Node end){
LinkedList<String> steps = new LinkedList<>();
Node p = end;
while (p != null) {
steps.addFirst(p.op);
p = p.prev;
}
steps.add("完成:已有 " + end.a + " 或 " + end.b + " 等于目标");
return steps;
}
staticintgcd(int a, int b){ return b == 0 ? a : gcd(b, a % b); }
// 小样例
publicstaticvoidmain(String[] args){
int X = 3, Y = 5, T = 4;
List<String> ans = solve(X, Y, T);
ans.forEach(System.out::println);
}
}
复杂度
BFS 最多遍历 (X+1)*(Y+1) 个状态,所以时间、空间都在 O(XY) 量级。坑点两个:一是先做可行性剪枝(t 超界或不整除 gcd),省掉无谓搜索;二是倒水时别忘了“倒到对方满了或自己空了为止”的两重限制,用 min(当前, 对方剩余) 一把梭。
就这样,思路清、代码短、还能把完整操作步骤打出来。你把 X、Y、T 换成面试官给的就行,过。
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html