#include"3197.h"
#define INF 0x3f3f3f3f
#define fastio cin.tie(0)->sync_with_stdio(0)
using namespace std;
typedef pair<int, int> pii;
// 실수 1. using namespace std 뒤에 typedef 선언해야 되는거 몰랐음
// 실수 2. vector 제대로 초기화 안 하고 새로 선언으로 떼우려고 함.
// 실수 3. 물이랑 겹치는 것만 넣어야 되는데, 모든 얼음을 큐에 넣어버렸음.
// 실수 4. 오리 둘 다 bfs 때려야 얼음이 골고루 녹는데 한 오리만 bfs 때림
// 실수 5. 오리 둘 다 bfs 때려도 얼음이 감싼 얼음은 안 녹음. 따로 bfs 해야됨.
// 이전 체크에서 얼음이었던 곳에서부터 bfs 다시 시작하도록 하여 최적화했는데 시간초과
bool IsValidXY(int& R, int& C, vector<string>& lake, int& newx, int& newy)
{
if (0 <= newx && newx < R && 0 <= newy && newy < C) return true;
else return false;
}
void B3197::Solution()
{
fastio;
// 얼음 녹인 뒤에 오리 한 쪽에서부터 갈 수 있는지 체크.
// 근데 이전 체크에서 얼음이었던 곳에서부터 bfs 다시 시작함.
int R, C;
string s;
cin >> R >> C;
vector<string> lake(R);
pii duck;
queue<pii> iceq;
vector<int> dx = { 1,-1,0,0 };
vector<int> dy = { 0,0,1,-1 };
vector<vector<bool>> visited(R, vector<bool>(C));
vector<vector<bool>> willmelt(R, vector<bool>(C));
for (int i = 0; i < R; i++) {
cin >> lake[i];
}
// 녹일 얼음을 확인
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
if (lake[i][j] == 'L') { duck = { i,j }; }
else if (lake[i][j] == 'X') {
for (int k = 0; k < 4; k++) {
int newx = i + dx[k];
int newy = j + dy[k];
if (IsValidXY(R, C, lake, newx, newy)
&& lake[newx][newy] == '.') {
willmelt[i][j] = true;
iceq.push({ i,j });
break;
}
}
}
}
}
bool done = false;
int day = 0;
queue<pii> duckq;
duckq.push(duck);
visited[duck.first][duck.second] = true;
while (true)
{
// 오리가 방문하지 않은 물을 전부 탐색
while (!duckq.empty()) {
pii d = duckq.front(); duckq.pop();
for (int i = 0; i < 4; i++) {
int newx = d.first + dx[i];
int newy = d.second + dy[i];
if (IsValidXY(R, C, lake, newx, newy)
&& !visited[newx][newy])
{
if (lake[newx][newy] == '.') {
visited[newx][newy] = true;
duckq.push({ newx,newy });
}
else if (lake[newx][newy] == 'L') {
done = true;
break;
}
}
}
if (done) break;
}
if (done) break;
// 얼음을 녹일 때 상하좌우 확인하고 다음 녹일 얼음 확인
int iceqlen = iceq.size();
while(iceqlen--) {
pii ice = iceq.front(); iceq.pop();
int icex = ice.first, icey = ice.second;
lake[icex][icey] = '.';
bool newduck = false;
for (int i = 0; i < 4; i++) {
int newx = icex + dx[i], newy = icey + dy[i];
if (IsValidXY(R, C, lake, newx, newy))
{
// 상하좌우에 오리가 방문한 물이 있다면 오리 큐에 추가
if (visited[newx][newy] && lake[newx][newy] == '.') {
newduck = true;
}
// 상하좌우에 아직 녹을 예정도 아닌 얼음이 있다면 녹일 예약
else if (!willmelt[newx][newy] && lake[newx][newy] == 'X') {
willmelt[newx][newy] = true;
iceq.push({ newx,newy });
}
}
}
if (newduck) {
visited[icex][icey] = true;
duckq.push(ice);
}
}
// 얼음을 녹일 때 중복 계산을 하지 않도록 visited를 체크하면
// 다음 duck bfs 때 visited 하지 않은 얼음을 nextdq에 담아놓을 수 없다
// willmelt를 선언한 후 얼음 녹는 bfs는 따로 체크한다면
// 시간 초과 발생했던 풀이가 됨
// 문제가 발생한 부분 : nextdq? > 하지만 그래봤자 계산 증가 최대 x3
// 얼음을 녹일 때 상하좌우에 visited한 물이 있고
// 그 얼음이었던 물을 다음 duckq에 넣어놓아야 한다.
// 오리가 긁고 간 자리를 기억해두려면 별도의 큐가 필요함, 그건 비효율
// 얼음이 녹을 때 오리가 갈 자리라면 오리 큐에 넣어둬야 함
// 얼음이 녹을 때 중복 계산을 막기 위해 얼음에 visited를 한다
day++;
}
cout << day;
}
3트인데도 안돼서 답지 보기로
네트워크 : 컴퓨터랑 컴퓨터 연결하여 데이터 교환이나 협력하는 통신망
네트워크 사용 이유
랜(Local Area Network, LAN) : 건물 안이나 특정 지역을 범위로 하는 네트워크
왠(Wide Area Network, WAN) : 2개 이상의 랜을 연결한 것
네트워크 구성 장치
대역폭(bandwidth) : 1초당 처리할 수 있는 데이터 양, (용량 x 8) / 처리 시간으로 구한다.
데이터 처리 단위
프로토콜 : 통신할 때 메시지 주고받는 규칙
OSI 7계층
OSI 7계층 데이터 표현
데이터에 든 거
포트 번호 : 애플리케이션 구분하기 위한 번호
IP 주소 : 인터넷에 연결된 모든 장치를 구분하기 위한 고유 주소. 인터넷 서비스에 가입하면 할당받음. 네트워크 계층에서 사용.
MAC 주소 : 하드웨어 장치에 할당된 주소. 컴퓨터 구매할 때부터 할당됨. 데이터 링크 계층에서 사용.
TCP/IP 4 계층
헤더 : 각 계층을 지나면서 덧붙여지는 정보
캡슐화 : 헤더가 추가되는 과정
역캡슐화 : 헤더가 분리되는 과정
VPN(Virtual Private Network, 가상사설망)
1. VPN 클라 소프트웨어 설치
2. VPN 서버 연결 및 인증
3. 데이터 암호화
4. 터널링으로 암호화 데이터 전송
랜 카드 : 데이터를 전기 신호로 변환
리피터 : 전기 신호를 증폭 (요즘엔 잘 안 씀)
허브 : 전송된 데이터 신호를 복원하고 증폭, 하나의 입력 신호를 여러 디바이스로 복제
데이터 계층 오류 감시 및 수정 방식
이더넷(Ethernet) : 다수의 컴퓨터, 허브, 스위치를 하나의 인터넷 케이블에 연결한 네트워크 구조
MAC(Media Access Control) 주소 : 랜 카드에 할당된 값. 전 세계에서 하나만 존재.
프레임
ARP로 MAC 주소 알아내는 과정 (기본적으론 LAN에서만 가능, WAN 환경에선 라우터 장비 거쳐야 확인 가능)
1. 컴퓨터 A가 같은 허브에 묶인 모든 컴퓨터에게 특정 IP 주소의 MAC 주소 물음.
스위치
단방향 통신 : 일방적으로 데이터 전송
양방향 통신 : 하나의 통신 채널에서 송수신이 모두 가능
충돌 도메인 : 충돌이 발생할 때 그 영향이 미치는 범위. 하나의 허브에 컴퓨터들이 연결돼있으면 여기 연결된 모든 컴퓨터가 충돌 도메인.