[白俊]18500鉱物2(Java)
質問する
昌栄と尚勤は洞窟で所有権を主張した.二人は棒を相手に投げる方法で誰に属するかを決める.戦いは洞窟で繰り広げられる.洞窟には鉱物が貯蔵されており、投げた棒は鉱物を破壊する可能性がある.
洞窟はR行C列、R列として表示できます.×C格子からなる.各格子は空またはミネラルを含み、隣接する2つの4つの方向の1つのミネラルを含む格子は同じ群である.
昌永は洞窟の左側に立っていて、上根は右側に立っています.二人は交代で棒を投げた.棒を投げる前に投げる高さを決めます.棒が地面と平らに飛ぶ.
木の棒が鉱物にぶつかると、格子の中の鉱物が破壊され、木の棒はその場で移動を停止します.
鉱物が破壊されると、残りのクラスタが分離される可能性があります.新しく生成されたクラスタが浮遊すると、重力は底部まで下がります.降下の間、クラスタの形状は変化しません.クラスタは、別のクラスタまたは土地に遭遇する前に、クラスタから分離される.クラスタ内で他のクラスタにドロップし、マージできます.
洞窟の中の鉱物の形と二人で投げた棒の高さ.すべての棒を投げ終わったら、鉱物の形を得るプログラムを書いてください.
入力
第1列は、穴の大きさRおよびCを与える.(1 ≤ R,C ≤ 100)
次のR行にはC文字,"."スペース、xは鉱物を表します.
次の行は棒を投げる回数Nを与える.(1 ≤ N ≤ 100)
最後の行にはレバーの高さがあり、スペースで区切られています.すべての高さは1とRの間にあり、高さ1は行列の最下部を表し、Rは最上位を表す.1本目の棒は左から右に投げ、2本目は右から左に投げ、このように順番に投げます.
空中に浮かぶ鉱物の群れもなく、2つ以上の群れが同時に落下することもない.
しゅつりょく
鉱物形状を入力形式と同じ形式で出力します.
I/O例
に答える
コード#コード#
import java.io.*;
import java.util.*;
public class Main_B18500 {
static char[][]map;
static int R,C;
static boolean[][] vistied;
static int[]dx= {1,-1,0,0};
static int[]dy= {0,0,1,-1};
static Queue<int[]>cluster=new LinkedList<>();;
public static void main(String[] args) throws IOException {
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st=new StringTokenizer(br.readLine());
StringBuilder sb=new StringBuilder();
R=Integer.parseInt(st.nextToken());
C=Integer.parseInt(st.nextToken());
map=new char[R][C];
for(int i=0;i<R;i++)map[i]=br.readLine().toCharArray();
int cnt=Integer.parseInt(br.readLine());
st=new StringTokenizer(br.readLine());
for(int t=0;t<cnt;t++){
int height=R-Integer.parseInt(st.nextToken());
remove(t%2,height);
vistied=new boolean[R][C];
//바닥에 있는 미네랄 모두 방문 체크
for(int i=0;i<C;i++) {
if(map[R-1][i]=='x'&&!vistied[R-1][i])
bfs(R-1,i);
}
boolean downCheck=false;
//공중에 있는 클러스터를 찾아 아래로
//문제에서 1개이하의 클러스터만 떨어진다고 했으므로 하나가 떨어지면 반복문 종료
for(int i=0;i<R;i++) {
if(downCheck)break;
for(int j=0;j<C;j++) {
if(map[i][j]=='x'&&!vistied[i][j]) {
bfs(i,j);
down();
downCheck=true;
break;
}
}
}
}
for(char[]a:map) {
for(char c:a) {
sb.append(c);
}
sb.append("\n");
}
bw.write(sb.toString());
bw.flush();
}
//높이와 방향에 따라 미네랄 파괴
static void remove(int d,int height) {
int i=0;
if(d==0) {
for(i=0;i<C;i++) {
if(map[height][i]=='x') {
map[height][i]='.';
break;
}
}
}
else {
for(i=C-1;i>=0;i--) {
if(map[height][i]=='x') {
map[height][i]='.';
break;
}
}
}
}
//클러스터 찾기
static void bfs(int x,int y) {
Queue<int[]>q=new LinkedList<>();
cluster.clear();
cluster.add(new int[] {x,y});
q.add(new int[] {x,y});
vistied[x][y]=true;
while(!q.isEmpty()) {
int[]temp=q.poll();
for(int i=0;i<4;i++) {
int nx=temp[0]+dx[i];
int ny=temp[1]+dy[i];
if(nx>=0&&ny>=0&&nx<R&&ny<C&&!vistied[nx][ny]&&map[nx][ny]=='x') {
vistied[nx][ny]=true;
cluster.add(new int[] {nx,ny});
q.add(new int[] {nx,ny});
}
}
}
}
//분리되어 있는 클러스터를 아래로 이동
static void down() {
int[][]temp=new int[cluster.size()][2];
int i=0,minus=0,size=temp.length;
while(!cluster.isEmpty()) {
temp[i++]=cluster.poll();
}
change(0, size, temp, '.');
while(true) {
if(check(minus+1, size, temp))minus++;
else break;
}
change(minus, size, temp, 'x');
}
//map 상태 변경
static void change(int minus,int size,int[][] temp,char c) {
for(int i=0;i<size;i++) {
int nx = temp[i][0]+minus;
int ny = temp[i][1];
map[nx][ny]=c;
}
}
//내려갈 수 있는지 확인
static boolean check(int minus,int size,int[][] temp) {
for(int i=0;i<size;i++) {
int nx = temp[i][0]+minus;
int ny = temp[i][1];
if(nx>=R||map[nx][ny]=='x') return false;
}
return true;
}
}
Reference
この問題について([白俊]18500鉱物2(Java)), 我々は、より多くの情報をここで見つけました https://velog.io/@jihun333/백준18500-미네랄-2-자바テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol