일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- dfs
- 소프티어
- ros
- BFS
- 마이크로프로세서
- ICER
- 시뮬레이션
- 왕실의기사대결
- 토끼와 경주
- 코드트리
- 싸움땅
- 포탑부수기
- 코드트리빵
- 백준
- DenseDepth
- 나무박멸
- 루돌프의반란
- ARM
- 마법의숲탐색
- 이진탐색
- DP
- 슈퍼컴퓨터클러스터
- 조합
- 수영대회결승전
- 순서대로방문하기
- 3Dreconstruction
- 삼성기출
- 구현
- Calibration
- ISER
Archives
- Today
- Total
from palette import colorful_colors
[SWEA] 1767 프로세서 연결하기 with C++ 본문
재귀를 꼭 써야만 하는 문제. 백트래킹으로 가지치기를 해야 시간초과가 발생하지 않는 문제
dfs로 접근했습니당
나의 가지치기 방법: 전선을 만들지 않고 재귀 돌리기 + for문으로 전선 만들고 재귀 돌리기
다른 가지치기 방법: 재귀 돌리다가 현재 연결한 코어 개수 + 남은 코어 수 < max코어수 면 더 재귀 돌릴 필요도 없음. return하기
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
struct coor {
int x;
int y;
};
struct answers {
int processor;
int wire;
};
int T, N;
int MAP[13][13];
int dx[4] = { -1, 1, 0, 0 };
int dy[4] = { 0, 0, -1, 1 };
int wireCount;
vector <coor> processors;
vector <answers> answerList;
int connectedProcessors;
int connectedProcessorsMax;
bool compare(answers a, answers b) {
if (a.processor == b.processor)
return a.wire < b.wire;
return a.processor > b.processor;
}
void init() {
memset(MAP, 0, sizeof(MAP));
processors.clear();
answerList.clear();
wireCount = 0;
connectedProcessors = 0;
connectedProcessorsMax = 0;
}
void dfs(int level) {
// 모두 시도해봤으면 return, vector에 넣기
if (level == processors.size()) {
if (connectedProcessors >= connectedProcessorsMax) {
connectedProcessorsMax = connectedProcessors;
answerList.push_back({ connectedProcessors, wireCount });
}
return;
}
// level번재 프로세서 하나 꺼내서 길 만들 수 있으면 전선 만들기
for (int k = 0; k < 4; k++)
{
int curX = processors[level].x;
int curY = processors[level].y;
vector<coor> temp;
bool canConnect = false;
int curWire = 0;
// 해당 방향으로 테스트해보기
while (1)
{
int nx = curX + dx[k];
int ny = curY + dy[k];
// 전선이 다른 전선에 닿거나 또다른 프로세서에 닿는 경우
if (MAP[nx][ny] == 2 || MAP[nx][ny] == 1) {
break;
}
// 벗어나면 브레이크
if ((nx < 0 || ny < 0 || nx >= N || ny >= N)) {
canConnect = true;
break;
}
temp.push_back({ nx, ny }); // 빈칸일경우, wire만들 곳 담기
curX = nx;
curY = ny;
}
// 해당 방향으로 길을 만들 수 있다면 dfs 돌리기, 복구하기
if (canConnect == true) {
for (int path = 0; path < temp.size(); path++){
coor curWire = temp[path];
MAP[curWire.x][curWire.y] = 2;
}
wireCount += temp.size();
connectedProcessors++;
dfs(level + 1);
for (int path = 0; path < temp.size(); path++)
{
coor curWire = temp[path];
MAP[curWire.x][curWire.y] = 0;
}
wireCount -= temp.size();
connectedProcessors--;
}
}
dfs(level+1);
}
void solve() {
dfs(0);
sort(answerList.begin(), answerList.end(), compare);
}
int main() {
//freopen("sample_input.txt", "r", stdin);
cin >> T;
for (int tc = 1; tc <= T; tc++) {
init();
cin >> N;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
cin >> MAP[i][j];
if (MAP[i][j] == 1) {
// 만약 가장자리에 있다면 카운트해주기
if (i == 0 || j == 0 || i == N - 1 || j == N - 1)
connectedProcessors++;
// 가장자리에 없는 프로세서는 벡터에 넣어주기
else
processors.push_back({ i, j });
}
}
}
solve();
cout << "#" << tc << " " << answerList[0].wire << "\n";
}
return 0;
}
'알고리즘 > 문제풀이' 카테고리의 다른 글
[SWEA] 2382 미생물 격리 with C++ (0) | 2024.02.21 |
---|---|
[백준] 14503 로봇 청소기 with C++ (삼성기출) (1) | 2024.02.19 |
[백준] 15685 드래곤 커브 with C++ (삼성기출) (1) | 2024.02.19 |
[SWEA] 5656 벽돌깨기 with C++ (0) | 2024.02.19 |
[SWEA] 5650 핀볼 게임 with C++ (0) | 2024.02.18 |