致力于解决这个问题
https://mines20.kattis.com/problems/mines20.paintbucket
使用TreeSet的Java解决方案超时,时间限制小于3秒
public class PaintBucketCSMinesSolution {
public static void main(String[] args) throws IOException {
// maintain distinct list of points that have been visited
Set<int[]> exploredSet = new TreeSet<>(
Comparator.comparingInt((int[] el) -> el[1]).thenComparingInt(el -> el[0]));
int W;
int H;
int X;
int Y;
int[][] picture;
BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(r.readLine());
W = Integer.parseInt(st.nextToken());
H = Integer.parseInt(st.nextToken());
X = Integer.parseInt(st.nextToken());
Y = Integer.parseInt(st.nextToken());
picture = new int[H][W];
for (int i = 0; i < H; i++) {
st = new StringTokenizer(r.readLine());
for (int j = 0; j < W; j++) {
picture[i][j] = Integer.parseInt(st.nextToken());
}
}
int color = picture[Y][X];
Stack<int[]> toExploreStack = new Stack<>();
toExploreStack.add(new int[] { X, Y });
while (!toExploreStack.isEmpty()) {
int[] point = toExploreStack.pop();
int px = point[0];
int py = point[1];
// System.out.println(exploredSet.contains(point));
boolean execute = true;
if (exploredSet.contains(point)) {
execute = false;
}
if (execute) {
exploredSet.add(point);
if (px > 0 && picture[py][px - 1] == color) {
toExploreStack.add(new int[] { px - 1, py });
}
if (px < (W - 1) && picture[py][px + 1] == color) {
toExploreStack.add(new int[] { px + 1, py });
}
if (py > 0 && picture[py - 1][px] == color) {
toExploreStack.add(new int[] { px, py - 1 });
}
if (py < (H - 1) && picture[py + 1][px] == color) {
toExploreStack.add(new int[] { px, py + 1 });
}
}
}
// exploredSet.sort(Comparator.comparingInt((int[] el) ->
// el[1]).thenComparingInt(el -> el[0]));
// Sorting HashSet using List
for (int[] v : exploredSet) {
System.out.println(v[0] + " " + v[1]);
}
}
}
Python中的解决方案在2.65秒内成功完成所有测试用例
W, H,X,Y = map(int, input().split())
picture=[]
for y in range(H):
picture.append([int(c) for c in input().split()])
#print(picture)
# implement a stack
to_explore = [(X , Y)]
explored=set()
color = picture[Y][X]
#print("color" , color)
while len(to_explore) >0:
px, py = to_explore.pop()
if(px, py) in explored:
continue
explored.add((px, py))
if (px > 0 and picture[py][px - 1] == color) :
to_explore.append( (px - 1, py ))
if (px < (W - 1) and picture[py][px + 1] == color) :
to_explore.append((px + 1, py ))
if (py > 0 and picture[py - 1][px] == color) :
to_explore.append( (px, py - 1) )
if (py < (H - 1) and picture[py + 1][px] == color) :
to_explore.append(( px, py + 1) )
for x,y in sorted(explored, key=lambda x: (x[1], x[0])):
print(x, y)
CPP溶液在2.05秒内完成
#include <algorithm>
#include <array>
#include <iostream>
#include <set>
#include <stack>
#include <vector>
int main() {
// comparison to sort the set naturally on inserting elements
const auto compare = [](const std::array<int, 2> &lhs,
const std::array<int, 2> &rhs) {
return lhs[1] < rhs[1] || (lhs[1] == rhs[1] && lhs[0] < rhs[0]);
};
// set to maintain unique elements as it is used for lookup to check if we have visited the node already
std::set<std::array<int, 2>, decltype(compare)> exploredSet(compare);
// std::set<std::array<int, 2>> exploredSet;
int W;
int H;
int X;
int Y;
// std::vector<std::vector<int>> picture;
std::cin >> W;
std::cin >> H;
std::cin >> X;
std::cin >> Y;
int picture[W][H];
for (int i = 0; i < H; i++) {
for (int j = 0; j < W; j++) {
std::cin >> picture[i][j];
}
}
int color = picture[Y][X];
std::stack<std::array<int, 2>> toExploreStack;
toExploreStack.push({X, Y});
while (!toExploreStack.empty()) {
std::array<int, 2> point = toExploreStack.top();
toExploreStack.pop();
int px = point[0];
int py = point[1];
bool execute = true;
// plain for loop was slow, this method is fast
if (exploredSet.count(point) == 1) {
execute = false;
}
if (execute) {
exploredSet.insert(point);
if (px > 0 && picture[py][px - 1] == color) {
toExploreStack.push({px - 1, py});
}
if (px < (W - 1) && picture[py][px + 1] == color) {
toExploreStack.push({px + 1, py});
}
if (py > 0 && picture[py - 1][px] == color) {
toExploreStack.push({px, py - 1});
}
if (py < (H - 1) && picture[py + 1][px] == color) {
toExploreStack.push({px, py + 1});
}
}
}
for (std::array<int, 2> v : exploredSet) {
std::cout << v[0] << " " << v[1] << std::endl;
}
}
请帮助优化Java解决方案。我已经没有办法了。
已经试过了
- HashMap并在end中排序
- HashSet并在最后排序。
同样令人惊讶的是,在这种情况下,Python能够比Java实现更快地完成。
1条答案
按热度按时间a11xaf1n1#
TreeSet
与自定义比较器结合使用时,开销似乎太大。HashSet
版本应该可以工作,并且与其他版本的逻辑相同。你只需要处理对象就可以得到正确的hashCode
。您可以尝试将相关行更改为: