[SWEA]1767番プロセッサの接続
🔔 質問する
https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV4suNtaXFEDFAUf
🎯 解答方法 N:セルサイズ(7≦N≦12) ユニット:地図 、コアと電線を含む MinWireLength:最小電線長合計 maxcore:最大カーネル数(0≦maxcore≦12) coreList:コア位置(行、列)を含むList dx(列)、dy(行):上、下、左、右 1.入力したセルがcoreの場合
1-1. エッジのcoreであればcoreListにX
1-2. そうでなければcoreListにOを保存する
2.電線を接続するDFS(Start Connect)
パラメータ:現在位置(idx)、現在コア数(corecnt)、現在電線接続(wirecnt)
①現在のコア位置の取得
②このコア位置をあちこち探索(上、下、左、右)
③一方向に進む場合、範囲外になると他のコアや電線に遭遇しないことを意味→中断
④途中で他のコアや電線に遭遇した場合は方向を変えて再カウント
⑤③、④さもなければ電線長が1増加
⑥カウントがない場合は、インデックスを1つ追加するだけでDFSが得られます
ü計算されている場合は、DFSを取得するために情報を蓄積する
💡 この問題を通して得られたもの
完全ナビゲーション(DFS)+シミュレーションの問題
💻 Javaコード
メモリ24344 kb、実行時間709ミリ秒、コード長2778
https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV4suNtaXFEDFAUf
🎯 解答方法
1-1. エッジのcoreであればcoreListにX
1-2. そうでなければcoreListにOを保存する
2.電線を接続するDFS(Start Connect)
パラメータ:現在位置(idx)、現在コア数(corecnt)、現在電線接続(wirecnt)
①現在のコア位置の取得
②このコア位置をあちこち探索(上、下、左、右)
③一方向に進む場合、範囲外になると他のコアや電線に遭遇しないことを意味→中断
④途中で他のコアや電線に遭遇した場合は方向を変えて再カウント
⑤③、④さもなければ電線長が1増加
⑥カウントがない場合は、インデックスを1つ追加するだけでDFSが得られます
ü計算されている場合は、DFSを取得するために情報を蓄積する
💡 この問題を通して得られたもの
完全ナビゲーション(DFS)+シミュレーションの問題
💻 Javaコード
メモリ24344 kb、実行時間709ミリ秒、コード長2778
import java.util.*;
import java.io.*;
class Solution
{
static class Core {
int x,y; // 열, 행
public Core(int y, int x) {
this.y = y;
this.x = x;
}
}
static int N, cell[][], minWireLength, maxCore;
static int dx[] = {0,0,-1,1}; // 상 하 좌 우
static int dy[] = {-1,1,0,0};
static List<Core> coreList; // 코어 위치 담을 리스트
public static void main(String args[]) throws Exception
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
StringBuilder sb = new StringBuilder();
int T = Integer.parseInt(br.readLine());
for(int t=1; t<=T; t++) {
N = Integer.parseInt(br.readLine());
cell = new int[N][N];
coreList = new ArrayList<>();
// 입력
for(int i=0; i<N; i++) {
st = new StringTokenizer(br.readLine());
for(int j=0; j<N; j++) {
int in = Integer.parseInt(st.nextToken());
if(in==1) {
cell[i][j] = in;
// 가장자리에 있는 코어라면 리스트에 저장X
if(i==0 || j==0 || i==N-1 || j==N-1)
continue;
coreList.add(new Core(i,j)); // 행, 열
}
}
}
minWireLength = Integer.MAX_VALUE;
maxCore = Integer.MIN_VALUE;
startConnect(0,0,0);
sb.append("#"+t+" "+minWireLength+"\n");
}
System.out.println(sb.toString());
}
public static void startConnect(int idx, int coreCnt, int wireCnt) {
if(idx == coreList.size()) {
if(maxCore < coreCnt) { // 최대한 많은 core에 연결
maxCore = coreCnt;
minWireLength = wireCnt;
} else if(maxCore == coreCnt) { // 전선길이의 합이 최소가 되는 값
minWireLength = Math.min(wireCnt, minWireLength);
}
return;
}
// 인덱스 위치의 코어의 좌표
int x = coreList.get(idx).x;
int y = coreList.get(idx).y;
// 상 하 좌 우 탐색
for(int dir=0; dir<4; dir++) {
int count=0, nx=x, ny=y;
while(true) {
nx += dx[dir];
ny += dy[dir];
// 범위를 벗어났다 is 다른코어나 전선을 만나지 않음
if(ny<0 || ny>=N || nx<0 || nx>=N) {
break;
}
// 가는 길에 다른 코어 혹은 전선 존재 -> 다른 방향으로
if(cell[ny][nx] == 1) {
count = 0;
break;
}
// 어떠한 방해도 없다면 +1
count++;
}
// count 갯수만큼 1로 채워줌
int fill_x = x;
int fill_y = y;
for(int i=0; i<count; i++) {
fill_x += dx[dir];
fill_y += dy[dir];
cell[fill_y][fill_x] = 1;
}
if(count==0)
startConnect(idx+1, coreCnt, wireCnt);
else {
startConnect(idx+1, coreCnt+1, wireCnt+count);
// 원본맵을 다시 0으로 되돌림
fill_x = x;
fill_y = y;
for(int i=0; i<count; i++) {
fill_x += dx[dir];
fill_y += dy[dir];
cell[fill_y][fill_x] = 0;
}
}
}
}
}
Reference
この問題について([SWEA]1767番プロセッサの接続), 我々は、より多くの情報をここで見つけました https://velog.io/@jeewoo1025/SWEA-프로세서-연결하기テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol