importjava.io.*;importjava.util.*;publicclassMain{staticintN;staticint[][]board;// memo[i][j][k] : k 방향으로 파이프를 두어 (i, j)에 도달 했을 떄의 경우의 수staticint[][][]memo;staticfinalintWALL=1;staticfinalintVERTICAL=0;staticfinalintHORIZONTAL=1;staticfinalintDIAGONAL=2;staticintgo(intr,intc,ints){if\(r<1\||r>N\||c<1\||c>N\||board\[r]\[c]==WALL)return0;if(memo[r][c][s]!=-1)returnmemo[r][c][s];memo[r][c][s]=0;if(s==VERTICAL){if(r-1>=1&&board[r-1][c]!=WALL){memo[r][c][s]+=go(r-1,c,VERTICAL);memo[r][c][s]+=go(r-1,c,DIAGONAL);}}elseif(s==HORIZONTAL){if(c-1>=1&&board[r][c-1]!=WALL){memo[r][c][s]+=go(r,c-1,HORIZONTAL);memo[r][c][s]+=go(r,c-1,DIAGONAL);}}else{if(r-1>=1&&c-1>=1&&board[r-1][c]!=WALL&&board[r][c-1]!=WALL){memo[r][c][s]+=go(r-1,c-1,VERTICAL);memo[r][c][s]+=go(r-1,c-1,HORIZONTAL);memo[r][c][s]+=go(r-1,c-1,DIAGONAL);}}returnmemo[r][c][s];}publicstaticvoidmain(String[]args)throwsException{BufferedReaderin=newBufferedReader(newInputStreamReader(System.in));N=Integer.parseInt(in.readLine());board=newint[N+1][N+1];memo=newint[N+1][N+1][3];for(int[][]d2:memo)for(int[]d1:d2)Arrays.fill(d1,-1);for(inti=1;i<=N;i++){StringTokenizerst=newStringTokenizer(in.readLine()," ");for(intj=1;j<=N;j++)board[i][j]=Integer.parseInt(st.nextToken());}memo[1][2][HORIZONTAL]=1;intres=0;for(ints=0;s<3;s++)res+=go(N,N,s);System.out.println(res);}}
BFS
r, c, dir를 갖는 Node class 생성
queue에서 pop한 Node의 방향에 따라 다음에 갈 수 있는 방향의 종류 및 수가 달라진다.
VERTICAL -> VERTICAL, DIAGONAL
HORIZONTAL -> HORIZONTAL, DIAGONAL
DIAGONAL -> VERTICAL, HORIZONTAL, DIAGONAL
대각선의 경우 현재 위치의 상대 좌표 (1, 1), (1, 0), (0, 1)이 모두 벽이 아니어야 가능하다