16号-バックグラウンド追跡-研究所(三星電子)

4762 ワード

注意事項


:ウイルスが拡散した場合、0の部分を2に変更
私たちは二人の友达として再び拡散しなければならないからです.

->このように再処理するのは論理的に間違っている.なぜなら.

->2つの区間を順番に呼び出し、古い番号の値が2になった場合
以前の区間ではウイルスが拡散できないという問題があったからです.
そのため、コードを変更する必要があります.

何回解けますか?


: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が正しいが,残りは間違っている.
  • 最終コード

  • の正確な条件は、tmpが2の場合にウイルス拡散に入ることであり、
  • である.
  • 付近の部分がウイルスと診断された場合、それを持って拡散し続けることでコードが変わります.


  • ソースコード

    #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; 
    
    	
    
    }