我一直试图通过广度优先搜索来解决这个问题http://dwite.ca/questions/haunted_house.html,但我无法让所有的测试用例都正确,而且我认为问题在于,它只计算直接的最短路径最后,它将计算任何糖果开放,但它不会计算通过糖果的最短路径这里是代码
import java.io.*;
import java.util.*;
public class HalloweenCandy {
static int n, candy;
static int minsteps, maxcandy;
static int totCandies=0;
public static void main(String[] args) throws FileNotFoundException {
Scanner s = new Scanner(new File("C:\\Users\\Daniel\\Desktop\\Java\\HalloweenCandy\\src\\halloweencandy\\DATA5.txt"));
while (s.hasNext()) {
n=Integer.parseInt(s.nextLine().trim());
char[][]maze=new char[n][n];
int xStart =0;
int yStart =0;
for(int y=0;y<n;++y){
String text = s.nextLine().trim();
for(int x=0;x<n;++x){
maze[x][y]=text.charAt(x);
if(maze[x][y]=='B'){
xStart=x;
yStart=y;
}
}
}
candy=0;
minsteps=0;
BFS(maze,xStart,yStart);
System.out.println(candy+" "+minsteps);
}
}
public static void BFS(char[][]maze,int xStart,int yStart){
Queue<int[]>queue=new LinkedList<int[]>();
int start[]={xStart,yStart,0,0};
queue.add(start);
while(queue.peek()!=null){
int[]array=queue.poll();
int x=array[0];int y=array[1];
if(x<0||y<0||y>n-1||x>n-1)continue;
if(maze[x][y]=='#')continue;
if(maze[x][y]=='*'){
candy++;
minsteps=array[2];
maze[x][y]='.';
}
if(maze[x][y]>='a'&&maze[x][y]<='f'){
if(candy <maze[x][y]-'a'+1)continue;
}
int[][]points = {{0,1},{1,0},{-1,0},{0,-1}};
for(int i=0;i<4;++i){
int sta[]={x+points[i][0],y+points[i][1],array[2]+1};
queue.add(sta);
}
maze[x][y]='#';
}
}
}
答案 0 :(得分:1)
你正处于写作轨道,但是你错过了重要的事情。
while(queue.peek()!=null){
int[]array=queue.poll();
int x=array[0];int y=array[1];
if(x<0||y<0||y>n-1||x>n-1)continue;
if(maze[x][y]=='#')continue;
if(maze[x][y]=='*'){
candy++;
minsteps=array[2];
maze[x][y]='.';
}
if(maze[x][y]>='a'&&maze[x][y]<='f'){
if(candy <maze[x][y]-'a'+1)continue;
}
int[][]points = {{0,1},{1,0},{-1,0},{0,-1}};
for(int i=0;i<4;++i){
int sta[]={x+points[i][0],y+points[i][1],array[2]+1};
queue.add(sta);
}
maze[x][y]='#'; // <== this part is wrong
}
你在最后一项任务中所做的是让你踏入墙上的每个方格。如果你可以在没有回溯的情况下通过迷宫,这将是正确的方法,但事实并非如此。相反,你想要做的就是确保在你拿起新的糖果之前不要回溯。所以,尝试这样的事情:
maze[x][y]='a'+candy;
这样,一旦你拿起一块新的糖果,这个方块就可以再次使用了。
然而,这里仍然存在问题。想想BFS如何在这张地图上运作:
3
...
*B*
...
如果[0,0]是左上方的图块,那么您的BFS算法将按以下顺序访问图块:[1,2],[2,1],[0,1],[1,0 ]。这有什么问题?比利正在他所有的邻近广场之间跳跃!你真正想要他做的是每次获得一块新糖果时重新启动BFS。我会留给你弄清楚如何做这个部分。
修改强> 的
以下是您要遵循的基本算法:
start
位置开始。start
另一个BFS。答案 1 :(得分:0)
我刚刚以你的方式解决了问题,&#34;贪心&#34;这里的方式是代码
import java.io.*;
import java.util.*;
public class HalloweenCandy {
static int n, candy;
static int minsteps, maxcandy;
static int totCandies = 0;
static boolean[][] is;
public static void main(String[] args) throws FileNotFoundException {
Scanner s = new Scanner(new File("C:\\Users\\Daniel\\Desktop\\Java\\HalloweenCandy\\src\\halloweencandy\\DATA5.txt"));
while (s.hasNext()) {
n = Integer.parseInt(s.nextLine().trim());
char[][] maze = new char[n][n];
is = new boolean[n][n];
int xStart = 0;
int yStart = 0;
for (int y = 0; y < n; ++y) {
String text = s.nextLine().trim();
for (int x = 0; x < n; ++x) {
maze[x][y] = text.charAt(x);
if (maze[x][y] == 'B') {
xStart = x;
yStart = y;
}
}
}
candy = 0;
int tot = 0;
int y = 0, x = 0;
x = xStart;
y = yStart;
for (int j = 0; j < n; ++j) {
for (int i = 0; i < n; ++i) {
is[i][j] = false;
}
}
while (true) {
char[][] grid = new char[n][n];
for (int j = 0; j < n; ++j) {
for (int i = 0; i < n; ++i) {
grid[i][j] = maze[i][j];
}
}
int lol[] = BFS(grid, x, y);
if (lol[0] == -1) {
break;
}
y = lol[2];
x = lol[1];
tot += lol[0];
}
System.out.println(candy + " " + tot);
}
}
public static int[] BFS(char[][] maze, int xStart, int yStart) {
Queue<int[]> queue = new LinkedList<int[]>();
int start[] = {xStart, yStart, 0, 0};
queue.add(start);
while (queue.peek() != null) {
int[] array = queue.poll();
int x = array[0];
int y = array[1];
if (x < 0 || y < 0 || y > n - 1 || x > n - 1) {
continue;
}
if (maze[x][y] == '#') {
continue;
}
if (maze[x][y] == '*' && !is[x][y]) {
is[x][y] = true;
candy++;
int sta[] = {array[2], x, y};
return sta;
}
if (maze[x][y] >= 'a' && maze[x][y] <= 'f') {
if (candy < maze[x][y] - 'a' + 1) {
continue;
}
}
int[][] points = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
for (int i = 0; i < 4; ++i) {
int sta[] = {x + points[i][0], y + points[i][1], array[2] + 1};
queue.add(sta);
}
maze[x][y] = '#';
}
int sta[] = {-1};
return sta;
}
}
我现在想弄清楚如何以动态方式解决它,我给出的解决方案仅适用于某些情况但不是全部。