ABC 211 E(DFS

E - Red Polyomino
题意:
给定一个 n × n n\times n n×n 的格子, ′ # ′ '\#' # 代表黑色, ′ . ′ '.' . 代表白色
我们每次选出 k k k 个白色的格子并涂成红色,并且红色格子必须是连通的(上下左右移动可以从任意一个红色格子到另外一个红色格子),求有多少种染色方案
思路:
D F S DFS DFS
方案去重的思路比较妙
code:

#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define ld long double
#define all(x) x.begin(), x.end()
#define mem(x, d) memset(x, d, sizeof(x))
#define eps 1e-6
using namespace std;
const int maxn = 4e2 + 9;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
ll n, m;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
char mp[10][10];
ll ans = 0;

void dfs(int cnt){
	if(cnt == 0){
		++ans;return;
	}
	vector <pair<int,int> > v;
	for(int i = 1; i <= n; ++i)
		for(int j = 1; j <= n; ++j){
			if(mp[i][j] == '.'){
				bool f = 0;
				for(int k = 0; k < 4; ++k){//找出是否存在红色格子可以到(i,j)
					int xx = i + dx[k], yy = j + dy[k];
					if(xx < 1 || yy < 1 || xx > n || yy > n) continue;
					if(mp[xx][yy] == '@') {
						f = 1;break;
					}
				}
				if(f){// 白色格子(i,j)四周存在红色格子
					mp[i][j] = '@';
					dfs(cnt - 1);
					mp[i][j] = '#';
					v.push_back({i, j});
				}
			}
		}
	for(auto d : v) mp[d.first][d.second] = '.'; 
}
void work()
{
	cin >> n >> m;
	for(int i = 1; i <= n; ++i) cin >> (mp[i] + 1);
	for(int i = 1; i <= n; ++i)
		for(int j = 1; j <= n; ++j){
			if(mp[i][j] == '.'){
				mp[i][j] = '@';// 涂成红色
				dfs(m - 1);// 还需要选m-1个
				mp[i][j] = '#';// 包含(i,j)格子的染色方案都求出来了,染成黑色防止后边再次选中(i,j)
			}
		}
	cout << ans;
}

int main()
{
	ios::sync_with_stdio(0);
	//int TT;cin>>TT;while(TT--)
	work();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值