[BaekJoon]303戦争-戦闘


1.  質問リンク


https://www.acmicpc.net/problem/1303

2.  質問する



サマリ

  • 隣接するN人が集まった時、N^2の威力が発生した時、白い服の兵士と青い服の兵士たちの配置であれば、白い服の兵士たちの威力の和と青い服の兵士たちの威力の和が問題となる.
  • 入力
  • :1行目は1以上、100以下の戦場横方向N、縦方向M、2行目は開始し、M行目は(X、Y)兵士の服の色を表示する.
  • 出力:1行目は白衣兵士の威力の和と青衣兵士の威力の和を出力する.
  • 3.  ソースコード

    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.util.StringTokenizer;
    
    public class Main {
    	static char[][] battlefield;
    	boolean[][] visited;
    	int[] soldierNum;
    	int count;
    	
    	public void dfs(int x, int y, char team) {
    		int[] dx = {-1, 0, 1, 0};
    		int[] dy = {0, -1, 0, 1};
    		visited[x][y] = true;
    		soldierNum[count]++;
    		for(int i = 0; i < 4; i++) {
    			int cx = x + dx[i];
    			int cy = y + dy[i];
    			if(cx >= 0 && cx < battlefield.length && cy >= 0 && cy < battlefield[0].length) {	
    				if(!visited[cx][cy] && battlefield[cx][cy] == team) {
    					dfs(cx, cy, team);
    				}
    			}
    		}
    	}
    	
    	public int[] getSumOfPower() {
    		if(battlefield.length == 1 && battlefield[0].length == 1) {
    			if(battlefield[0][0] == 'W') {
    				int[] sumOfPower = {1, 0};
    				return sumOfPower;
    			} else {
    				int[] sumOfPower = {0, 1};
    				return sumOfPower;
    			}
    		}
    		int[] sumOfPower = new int[2];
    		visited = new boolean[battlefield.length][battlefield[0].length];
    		soldierNum = new int[battlefield.length * battlefield[0].length];
    		for(int i = 0; i < battlefield.length; i++) {
    			for(int j = 0; j < battlefield[i].length; j++) {
    				if(!visited[i][j] && battlefield[i][j] == 'W') {
    					count++;
    					dfs(i, j, 'W');
    				}
    			}
    		}
    		for(int i = 0; i < soldierNum.length; i++) {
    			if(soldierNum[i] != 0) {
    				sumOfPower[0] += Math.pow(soldierNum[i], 2);
    			}
    		}
    		count = 0;
    		soldierNum = new int[battlefield.length * battlefield[0].length];
    		for(int i = 0; i < battlefield.length; i++) {
    			for(int j = 0; j < battlefield[i].length; j++) {
    				if(!visited[i][j] && battlefield[i][j] == 'B') {
    					count++;
    					dfs(i, j, 'B');
    				}
    			}
    		}
    		for(int i = 0; i < soldierNum.length; i++) {
    			if(soldierNum[i] != 0) {
    				sumOfPower[1] += Math.pow(soldierNum[i], 2);
    			}
    		}
    		return sumOfPower;
    	}
    	
    	public static void main(String[] args) throws IOException {
    		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    		String input = br.readLine();
    		StringTokenizer st = new StringTokenizer(input);
    		int row = Integer.parseInt(st.nextToken());
    		int col = Integer.parseInt(st.nextToken());
    		battlefield = new char[col][row];
    		for(int i = 0; i < col; i++) {
    			input = br.readLine();
    			for(int j = 0; j < row; j++) {
    				battlefield[i][j] = input.charAt(j);
    			}
    		}
    		br.close();
    		Main m = new Main();
    		int[] result = m.getSumOfPower();
    		bw.write(result[0] + " " + result[1] + "\n");
    		bw.flush();
    		bw.close();
    	}
    }

    4.  に近づく

  • この問題は、dfsを用いて隣接する兵士の数を得た後、dfsを用いて各兵士の威力を得ることができることである.
  • レイアウトを入力し、戦場サイズが1*1の場合、Wは10、Bは01を出力します.
  • 戦場でこの場所にアクセスしたかどうかを決定するために、アクセス配列が作成され、隣接する兵士の数と隣接する兵士の集合を表す番号を格納するcount変数が作成された.
  • 戦場の全体の位置を迂回して、隣接する白衣兵士の数と、その後隣接する青衣兵士の数を探します.
  • この場所がまだアクセスされておらず、検索する色である場合、dfsが実行されます.
  • は、その位置の上下左右をチェックしてその位置にアクセスするためのdx、dy配列を作成するので、アクセスでその位置をtrueに変更し、その位置に兵士が存在するためcount 1番目のsoliderNumの数を1増加させる.
  • の上下左右を検査し、その位置が戦場内(0,0)~(M−1,N−1)の間に存在し、まだその位置にアクセスしておらず、その位置に現在探している色の兵士がいる場合、その位置の上下左右を再帰的に決定する.
  • 位で隣接する白い服の兵士の数と隣接する青い服の兵士の数を求め、さらに各色の隣接兵士の数を乗じて2色の勢力を求めた.