[C++]白俊1941号:有名な七姫


質問リンク
1941号:有名な七姫
問題の概要
25人の学生の中から7人の学生を選出し、選ばれた学生は横または縦に隣接してグループを構成しなければならない.これらの学生のうち、4人以上の李多順派の学生を配置すれば、人数を聞く必要がある.
方法
25 C 7=4800700{25}C 7=480070025 C 7=480700なので、私たちが7人全員を試してみれば問題はなく、私たちの判断は正しいと思います.
  • 225人の中から7人が選ばれた.
  • この7名の生徒のうち4名以上が
  • 4人以上であれば、隣接しているかどうかを判断します.
  • 隣接するかどうかはBFSによって決まる.7人の学生をstd::setに保存し、1人の学生をstd::キューに入れました.次に、set内にいる学生をキューに入れ、setから削除します.このようにBFSを迂回してすべての7人にナビゲートできれば可能であると考えられる.
    コード#コード#
    #include <bits/stdc++.h>
    
    using namespace std;
    
    int n[6][6], res, dir[4][2] = { {1, 0}, {-1, 0}, {0, 1}, {0, -1} };
    char b[6][6];
    bool visited[26];
    pair<int, int> pos[26];
    vector<int> v;
    
    void func(int cnt, int idx)
    {
    	if (cnt == 7)
    	{
    		int s = 0;
    		for (auto& i : v)
    			if (b[pos[i].first][pos[i].second] == 'S')
    				s++;
    
    		if (s < 4)
    			return;
    
    		set<int> tmp;
    		for (auto& i : v)
    			tmp.insert(i);
    
    		int num = 0;
    		queue<int> q;
    		q.push(v[0]);
    		tmp.erase(v[0]);
    		while (!q.empty())
    		{
    			pair<int, int> now = pos[q.front()];
    			q.pop();
    			num++;
    
    			for (int i = 0; i < 4; i++)
    			{
    				int nr = now.first + dir[i][0], nc = now.second + dir[i][1];
    				int next = n[nr][nc];
    
    				if (nr >= 1 &&  nr <= 5 && nc >= 1 && nc <= 5 && tmp.find(next) != tmp.end())
    				{
    					tmp.erase(next);
    					q.push(next);
    				}
    			}
    		}
    
    		if (num == 7)
    			res++;
    		return;
    	}
    
    	for (int i = idx; i <= 25; i++)
    	{
    		if (!visited[i])
    		{
    			visited[i] = true;
    			v.push_back(i);
    			func(cnt + 1, i + 1);
    			visited[i] = false;
    			v.pop_back();
    		}
    	}
    }
    
    int main(void)
    {
    	int idx = 1;
    	for (int i = 1; i <= 5; i++)
    		for (int j = 1; j <= 5; j++)
    			cin >> b[i][j], n[i][j] = idx, pos[idx++] = { i, j };
    
    	func(0, 1);
    	cout << res;
    	return 0;
    }