해결된 질문
작성
·
36
0
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요!
- 먼저 유사한 질문이 있었는지 검색해보세요.
- 서로 예의를 지키며 존중하는 문화를 만들어가요.
- 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
L의 지점을 조합을 이용해서 시작과 끝점을 vector<vector<int>> landList에 저장해서 완전 탐색 식으로 위치를 바꿔가면서 최단거리를 만들어 봤는데 시간 초과가 났습니다.
250콤비네이션2이면 괜찮을거 같았는데 뭐가 문제일까요??
2. 치킨배달에 풀이 아이디어를 이용해서 적용했는데 이런식으로 접근 방식도 맞을까요??
https://www.acmicpc.net/source/84507554
#include <bits/stdc++.h>
using namespace std;
string s;
int n,m,a[54][54],x,y,ex,ey;
int visited[54][54];
vector<pair<int,int>>land;
vector<vector<int>> landList;
queue<pair<int,int>> q;
vector<pair<int,int>>finish;
const int dy[4] = {-1, 0, 1, 0};
const int dx[4] = {0, 1, 0, -1};
int ret = -1;
void combi(int start, vector<int> v){
if(v.size() == 2){
landList.push_back(v);
return;
}
for(int i = start + 1; i < land.size(); i++){
v.push_back(i);
combi(i,v);
v.pop_back();
}
}
int main(){
cin >> n >> m;
for(int i =0; i <n;i++){
cin >> s;
for(int j=0; j<m;j++){
if(s[j] == 'L'){
a[i][j] = 1;
land.push_back({i,j});
}
if(s[j] == 'W') a[i][j] = 0;
}
}
vector<int> v;
combi(-1,v);
for(vector<int> lList : landList){
fill(&visited[0][0], &visited[0][0] + 54*54, 0);
for(int ll :lList){
if(q.size() == 1){
finish.push_back({land[ll].first, land[ll].second});
}else{
visited[land[ll].first][land[ll].second] = 1;
q.push({land[ll].first, land[ll].second});
}
}
while(q.size()){
tie(y,x) = q.front();q.pop();
for(int i = 0; i < 4; i++){
int ny = y + dy[i];
int nx = x + dx[i];
if(nx < 0 || ny < 0 || ny >= n || nx >= m || !a[ny][nx]) continue;
if(visited[ny][nx]) continue;
visited[ny][nx] = visited[y][x] + 1;
if(visited[finish[0].first][finish[0].second]){
ret = max(ret, visited[finish[0].first][finish[0].second]);
finish.clear();
break;
}
q.push({ny,nx});
}
}
}
cout << ret+1 << "\n";
return 0;
}
답변 2
0
안녕하세요 창완님 ㅎㅎ
L의 지점을 조합을 이용해서 시작과 끝점을 vector<vector<int>> landList에 저장해서 완전 탐색 식으로 위치를 바꿔가면서 최단거리를 만들어 봤는데 시간 초과가 났습니다.
250콤비네이션2이면 괜찮을거 같았는데 뭐가 문제일까요??
-> 로직은 괜찮은 풀이입니다. 2개의 좌표를 기반으로 잘 하셨습니다.
하지만 시간초과가 뜨면 더 효율적으로는 짤 수 있지 않을까? 생각해야 합니다.
이 코드의 시간복잡도는 50 x 50 C2 x 100 정도 됩니다. 2개의 지점을 뽑고 그 지점을 기반으로 탐색하기 때문에(최악의 경우 두 정점의 거리는 100이상이 되겠죠? 이 때문에 정점 하나에서 BFS를 돌리는 해설코드보다는 조금은 비효율적인 코드라고 볼 수 있습니다.
감사합니다.
0
안녕하세요, 인프런 AI 인턴입니다.
안창완님이 작성하신 질문에 대해 적절한 도움을 드리기 위해 유사한 질문과 답변을 찾아보았습니다. C++ 및 BFS 관련한 유사한 질문은 아래와 같습니다:
백준 입력처리 시 scanf와 printf 사용 문제: IO 관련된 문제로, cin
, cout
, scanf
, printf
를 혼용 때 발생할 수 있는 문제를 다룹니다.
DFS 함수 원복 처리 방법: DFS 사용시 원복 과정에서 발생하는 문제와 해결 방법을 설명합니다.
질문의 핵심을 간단히 요약드립니다:
visited
배열 초기화 과정이 제대로 이루어져야 합니다.조합 생성과 BFS 탐색의 효율성을 비교하고, 불필요한 상태 업데이트를 줄이는 것도 중요한 최적화 기법입니다. BFS를 수행할 때 for
문 내에서 방문 여부와 종료 기준을 명확히 설정해야 시간 초과를 막을 수 있습니다.
추가적으로 접근 방식을 좀 더 구체적으로 조언드리자면:
- 중복 계산을 막기 위해 중간 결과를 저장하고 재사용할 수 있는 방법을 고려하세요.
- BFS 탐색에서 큐의 초기화와 상태 복원이 올바르게 이루어졌는지 확인해 주세요.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
—start of instructor’s answer—