讲真的这个题目我现在觉得特别恶心,不是说难,弄了两种解决算法用JAVA写都没A,但是神奇的是用了c++写就可以直接A了,我把代码贴出来。
哦对,其中一个JAVA代码确实有问题,并且不知道BUG在哪里,是我的问题;
算法不再写了,贴完代码直接刷题去了。仍需努力啊!再哭一会。。
代码如下:
JAVA第一个代码,有BUG;
import java.util.Scanner; public class Curling_2 { static Scanner input = new Scanner(System.in); static int[][] Room = new int[20][20]; static int dir[][] = {{1,0},{-1,0},{0,1},{0,-1}}; //四个搜索方向 static int move=0; static int x,y; public static void main(String[] args){ int cou=1; while (true){ //初始化矩形空间的 宽 高,以及函数引用的存放起点座标的变量 x=input.nextInt(); y=input.nextInt(); if (x==0&&y==0) break; int m=0,n=0; for (int i=0;i<x;i++){ for (int j=0;j<y;j++){ //初始化 Room[i][j]=input.nextInt(); //寻找起点 if (Room[i][j]==2){ m=i; n=j; } } } search(m,n,cou); System.out.println(move); } } static void search(int a,int b,int mo){ if (mo>10){ move = -1; return; } else { for (int i=0;i<4;i++){ int h=a+dir[i][0]; int l=b+dir[i][1]; //如果选择方向以后第一次移动数不大于10并且是目标座标,返回移动数。 if (Room[h][l]==3) if (mo<=10){ move=mo; break; } //选择方向以后接着移动 while (h>=0&&h<x&& l>=0&&l<y &&Room[h][l]==0){ h+=dir[i][0]; l+=dir[i][1]; if (Room[h][l]==1){ search(h-dir[i][0],l-dir[i][1],mo+1); Room[h][l]=0; return; } if (Room[h][l]==3) if (mo<=10){ move=mo; return; } } } return; } } }
JAVA第二个代码无BUG:
import java.util.Scanner; import java.math.*; import java.lang.*; public class Curling2third { static int[][] s=new int[25][25]; static int result; static int sx, sy; static int n, m; static void dfs(int x, int y, int step, int type) { if (step > 10) return; //超过10步失败 //到达目的地 if (s[x][y] == 3) { if (result == -1) result = step; else result = Math.min(result, step); return; } //石头把墙撞碎 switch (type) { case 1: s[x - 1][y] = 0; break; //north case 2: s[x + 1][y] = 0; break; //south case 3: s[x][y - 1] = 0; break; //west case 4: s[x][y + 1] = 0; break; //east } //四处搜索寻找终点 for (int i = 1; i <= x; i++) { if (s[x - i][y] == 1) break; if (s[x - i][y] == 3) { dfs(x - i, y, step + 1, 0); break; } } for (int i = 1; i < m - x; i++) { if (s[x + i][y] == 1) break; if (s[x + i][y] == 3) { dfs(x + i, y, step + 1, 0); break; } } for (int i = 1; i <= y; i++) { if (s[x][y - i] == 1) break; if (s[x][y - i] == 3) { dfs(x, y - i, step + 1, 0); break; } } for (int i = 1; i < n - y; i++) { if (s[x][y + i] == 1) break; if (s[x][y + i] == 3) { dfs(x, y + i, step + 1, 0); break; } } //四处探索 if (x >= 1 && s[x - 1][y] != 1) for (int i = 2; i <= x; i++) if (s[x - i][y] == 1) { dfs(x - i + 1, y, step + 1, 1); break; } if (x + 1 < m && s[x + 1][y] != 1) for (int i = 2; i < m - x; i++) if (s[x + i][y] == 1) { dfs(x + i - 1, y, step + 1, 2); break; } if (y >= 1 && s[x][y - 1] != 1) for (int i = 2; i <= y; i++) if (s[x][y - i] == 1) { dfs(x, y - i + 1, step + 1, 3); break; } if (y + 1 < n && s[x][y + 1] != 1) for (int i = 2; i < n - y; i++) if (s[x][y + i] == 1) { dfs(x, y + i - 1, step + 1, 4); break; } //墙壁复原 switch (type) { case 1: s[x - 1][y] = 1; break; case 2: s[x + 1][y] = 1; break; case 3: s[x][y - 1] = 1; break; case 4: s[x][y + 1] = 1; break; } } public static void main(String[] args){ Scanner input=new Scanner(System.in); //freopen("3009.in","r",stdin); while (true) //m行n列 { m=input.nextInt(); n=input.nextInt(); if (n == 0 && m == 0) break; result = -1; for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) { s[i][j]=input.nextInt(); if (s[i][j] == 2) { sx = i; sy = j; } } dfs(sx, sy, 0, 0); System.out.println(result); } return; } }
C++代码,直接A了:
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace std; int s[25][25]; int result; int sx, sy; int n, m; void dfs(int x, int y, int step, int type) { if(step > 10) return; //超过10步失败 //到达目的地 if(s[x][y] == 3) { if(result == -1) result = step; else result = min(result, step); return; } //石头把墙撞碎 switch(type) { case 1: s[x-1][y] = 0; break; //north case 2: s[x+1][y] = 0; break; //south case 3: s[x][y-1] = 0; break; //west case 4: s[x][y+1] = 0; break; //east } //四处搜索寻找终点 for(int i=1; i<=x; i++) { if(s[x-i][y]==1) break; if(s[x-i][y]==3) { dfs(x-i, y, step+1, 0); break; } } for(int i=1; i<m-x; i++) { if(s[x+i][y]==1) break; if(s[x+i][y]==3) { dfs(x+i, y, step+1, 0); break; } } for(int i=1; i<=y; i++) { if(s[x][y-i]==1) break; if(s[x][y-i]==3) { dfs(x, y-i, step+1, 0); break; } } for(int i=1; i<n-y; i++) { if(s[x][y+i]==1) break; if(s[x][y+i]==3) { dfs(x, y+i, step+1, 0); break; } } //四处探索 if(x>=1 && s[x-1][y]!=1) for(int i=2; i<=x; i++) if(s[x-i][y]==1) { dfs(x-i+1, y, step+1, 1); break; } if(x+1<m && s[x+1][y]!=1) for(int i=2; i<m-x; i++) if(s[x+i][y]==1) { dfs(x+i-1, y, step+1, 2); break; } if(y>=1 && s[x][y-1]!=1) for(int i=2; i<=y; i++) if(s[x][y-i]==1) { dfs(x, y-i+1, step+1, 3); break; } if(y+1<n && s[x][y+1]!=1) for(int i=2; i<n-y; i++) if(s[x][y+i]==1) { dfs(x, y+i-1, step+1, 4); break; } //墙壁复原 switch(type) { case 1: s[x-1][y] = 1; break; case 2: s[x+1][y] = 1; break; case 3: s[x][y-1] = 1; break; case 4: s[x][y+1] = 1; break; } } int main(void) { //freopen("3009.in","r",stdin); while(scanf("%d%d",&n,&m)) //m行n列 { if(n==0 && m==0) return 0; result = -1; for(int i=0; i<m; i++) for(int j=0; j<n; j++) { scanf("%d",&s[i][j]); if(s[i][j]==2) {sx=i; sy=j;} } dfs(sx, sy, 0, 0); printf("%d\n",result); } return 0; }