16号-バックグラウンド追跡-研究所(三星電子)
4762 ワード
注意事項
:ウイルスが拡散した場合、0の部分を2に変更
私たちは二人の友达として再び拡散しなければならないからです.
->このように再処理するのは論理的に間違っている.なぜなら.
->2つの区間を順番に呼び出し、古い番号の値が2になった場合
以前の区間ではウイルスが拡散できないという問題があったからです.
そのため、コードを変更する必要があります.
何回解けますか?
:2号//09-24
ポリシー
:2号//09-24
ポリシー
壁を全部立てると、ウイルスが拡散します.
どのように3つの壁を立てて、そのため拡散していない場所がゼロの部分はカウントです.
最大サイズは8*8なので、プローブが完了しても時間の複雑さはあまり高くありません.
0の部分に1人壁を取り付けます.拡散を緩和するために、合計3回取り付けます.
(0,1)の部分も取り付け、(0,2)の部分も取り付け、このようにしゃがむ.
進行中、ウイルスが確定診断されていない部分を計算します.
どうすればいいですか.
(0,1)の部分に取り付けた後、再帰動作に入ります.それだけで
(0,1)にはインストールされず、次の部分にインストールされるため、完全なナビゲーションが可能になります.
これに基づいてコードを書き、
dfs(??)
{
//벽 설치하는 카운팅
//~~~~
for(int i ~ 세로 길이)
{
for(int j ~ 가로 길이 )
{
if(arr[i][j] == 0)
{
arr[i][j] = 1;
cnt += 1;
//이런식으로 해야만, arr[i][j] 가 0으로 놓고 탐색이 가능한 것이다.
dfs();
arr[i][j] = 0;
cnt -= 1;
}
}
}
}
考える部分
cntが3の場合、ウイルスの拡散を開始する必要があります.
壁を取り付け直しウイルスを拡散し直す必要があります
ウイルス拡散後の配列値は元の値に戻ってウイルス拡散する必要があるため、ウイルス拡散を行う一時変数を作成する必要があります.
ウイルスが拡散すると、上下左右に拡散し、ターゲットポイントを放出します.
この点が拡散したら、この点で拡散しましょう.
最初のコード
->これを使えば例1が正しいが,残りは間違っている.
最終コード
ソースコード #include <string>
#include <vector>
#include <queue>
#include <iostream>
using namespace std;
int n, m;
int cnt = 0;
vector<vector<int>>tmp;
vector<vector<int>>v;
int answer = 0;
//상하좌우
int dy[] = { -1,1,0,0 };
int dx[] = { 0,0,-1,1 };
void virus(int y, int x)
{
//상하좌우를 재귀로 처리하자.
for (int i = 0; i < 4; i++)
{
int ny = y + dy[i];
int nx = x + dx[i];
if (ny < 0 || ny >= n
|| nx < 0 || nx >= m)
continue;
if (tmp[ny][nx] == 0)
{
tmp[ny][nx] = 2;
virus(ny, nx);
}
}
}
void backTracking()
{
//바이러스 확산하자.
if (cnt == 3)
{
tmp = v;
//2일 때만 판단해서 virus 함수 호출하자.
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (tmp[i][j] == 2)
{
virus(i, j);
}
}
}
int result = 0;
//바이러스 확산 완료 후에 카운팅하자.
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (tmp[i][j] == 0)
{
result += 1;
}
}
}
answer = max(answer, result);
return;
}
//벽은 1, 바이러스는 2, 빈 공간은 0
//벽을 3개 세우면서 백트래킹 처리하자.
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (v[i][j] == 0)
{
v[i][j] = 1;
cnt += 1;
backTracking();
v[i][j] = 0;
cnt -= 1;
}
}
}
}
int main()
{
//벽 3개를 모두 세운뒤에 바이러스 확산 후에
//min값 계산하자.
cin >> n >> m;
v.resize(n, vector<int>(m));
//0은 빈칸, 1은 벽, 2는 바이러스이다.
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
cin >> v[i][j];
}
}
backTracking();
cout << answer;
}
Reference
この問題について(16号-バックグラウンド追跡-研究所(三星電子)), 我々は、より多くの情報をここで見つけました
https://velog.io/@kwt0124/백준-14502번-연구소
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
#include <string>
#include <vector>
#include <queue>
#include <iostream>
using namespace std;
int n, m;
int cnt = 0;
vector<vector<int>>tmp;
vector<vector<int>>v;
int answer = 0;
//상하좌우
int dy[] = { -1,1,0,0 };
int dx[] = { 0,0,-1,1 };
void virus(int y, int x)
{
//상하좌우를 재귀로 처리하자.
for (int i = 0; i < 4; i++)
{
int ny = y + dy[i];
int nx = x + dx[i];
if (ny < 0 || ny >= n
|| nx < 0 || nx >= m)
continue;
if (tmp[ny][nx] == 0)
{
tmp[ny][nx] = 2;
virus(ny, nx);
}
}
}
void backTracking()
{
//바이러스 확산하자.
if (cnt == 3)
{
tmp = v;
//2일 때만 판단해서 virus 함수 호출하자.
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (tmp[i][j] == 2)
{
virus(i, j);
}
}
}
int result = 0;
//바이러스 확산 완료 후에 카운팅하자.
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (tmp[i][j] == 0)
{
result += 1;
}
}
}
answer = max(answer, result);
return;
}
//벽은 1, 바이러스는 2, 빈 공간은 0
//벽을 3개 세우면서 백트래킹 처리하자.
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (v[i][j] == 0)
{
v[i][j] = 1;
cnt += 1;
backTracking();
v[i][j] = 0;
cnt -= 1;
}
}
}
}
int main()
{
//벽 3개를 모두 세운뒤에 바이러스 확산 후에
//min값 계산하자.
cin >> n >> m;
v.resize(n, vector<int>(m));
//0은 빈칸, 1은 벽, 2는 바이러스이다.
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
cin >> v[i][j];
}
}
backTracking();
cout << answer;
}
Reference
この問題について(16号-バックグラウンド追跡-研究所(三星電子)), 我々は、より多くの情報をここで見つけました https://velog.io/@kwt0124/백준-14502번-연구소テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol