1. 程式人生 > >ACM:POJ-1979 Red And Black(JAVA的字元陣列輸入以及標記方法)

ACM:POJ-1979 Red And Black(JAVA的字元陣列輸入以及標記方法)

對於該題目直接用DFS或者BFS都可以直接暴力出來,實際上題目也不難,只需要遞迴一個搜尋方法即可。那麼用C或者C++將很容易的解決這個題目。

但是如果用JAVA寫的話將存在一個昨晚讓我糾結了很久的問題:輸入資訊需要以字元陣列的形式儲存,那麼如何解決標記以及儲存的問題?

剛開始我定義了一個二維字元陣列,並且輸入用了整形輸入,然後通過強制轉換的方法將儲存轉化為字元型。但是實際上在執行的過程中就出現了輸入型別與定義型別不符的問題。程式碼如下:

import java.util.Scanner;

public class RedAndBlack {
    static Scanner input = new Scanner(System.in);

    static char[][] Room = new char[20][20];

    public static void main(String[] args){

        while (true){

            //初始化矩陣的列與行
            int y=input.nextInt();
            int x=input.nextInt();

            //如果行列均為0,結束程式
            if (x==0&&y==0)
                break;

            //初始化地板資訊
            for (int i=0;i<x;i++){
                for (int j=0;j<y;j++){
                    Room[i][j]=(char)input.nextInt();
                }
                System.out.println();
            }

            //記錄所有可以行走的地板
            for (int i=0;i<x;i++){
                for (int j=0;j<y;j++){
                    if (Room[i][j]=='@')
                        System.out.println(calcu(i,j,x,y));
                }

            }
        }
    }

    static int calcu(int a,int b,int h,int l){
        if (a<0||a>=h||b<0||b>=l)
            return 0;
        else if (Room[a][b]=='#')
            return 0;
        else{
            Room[a][b]='#';
            return 1+calcu((a+1),b,h,l)+calcu(a,(b+1),h,l)+calcu((a-1),b,h,l)+calcu(a,(b-1),h,l);
        }
    }
}

顯然這樣並不能解決字元型別的陣列輸入。所以我開始改用定義一個一維字串陣列,但是一樣存在一個問題:

當一塊地板已經被這個人踩了以後,即已經記錄在數目裡面,如果將這塊地板改為不能再踩,即如何標記出這塊地板已經被計算過。如果用類C語言將很容易解決這個問題,因為類C語言可以直接進行字元陣列或者用字串下腳標所以來進行資料更換。

顯然,在JAVA中沒有對於一個字串僅僅改掉其中某一個字元的方法的前提下,要想標記出一塊地板已經被記錄,只好再宣告一個二維整形陣列在初始化以後將已經被記錄的地板進行標記,最後再額外在搜尋函式中增加一個判斷是否記錄過的方法即可。

程式碼如下:

importjava.util.Scanner;
import 
java.lang.String; public class RedAndBlack { static Scanner input = new Scanner(System.in); static String[] Room = new String[20]; static int[][] judge=new int[20][20]; static int m,n; public static void main(String[] args){ while (true){ //初始化矩陣的列與行 n=input.nextInt(); m
=input.nextInt(); //如果行列均為0,結束程式 if (n==0&&m==0) break; for (int i=0;i<m;i++){ for (int j=0;j<n;j++){ judge[i][j]=0; } } //初始化地板資訊 for (int i=0;i<m;i++){ // System.out.println("hello"); //for (int j=0;j<y;j++){ // System.out.println(); Room[i]=input.next(); //} // System.out.println(); } //記錄所有可以行走的地板 for (int i=0;i<m;i++){ for (int j=0;j<n;j++){ if (Room[i].charAt(j)=='@') System.out.println(calcu(i,j)); } } } } static int calcu(int a,int b){ if (a<0||a>=m||b<0||b>=n) return 0; if (Room[a].charAt(b)=='#') return 0; if (judge[a][b]==1) //標記陣列0表示標記, 1表示記錄過 return 0; //所有滿足沒有標記過的地板,先標記為1然後再遞迴。 judge[a][b]=1; return 1+calcu((a+1),b)+calcu(a,(b+1))+calcu((a-1),b)+calcu(a,(b-1)); } }