暴力搜索加剪枝,二进制保存状态,set去重~
#include<bits/stdc++.h> using namespace std; const int maxn=7; string s[maxn]; struct node { int x,y; }Node[100]; int N,M,K,H; int g[maxn][maxn]; int visit[maxn][maxn]; int X[4]={1,0,-1,0}; int Y[4]={0,1,0,-1}; int judge (int x,int y) { if (x>N||x<1||y>M||y<1) return -1; if (g[x][y]>0) return 0; return 1; } unordered_set<long long> st; int cnt=0; int hole=0; long long ans=1; int result=0; void bfs () { queue<node> q; memset (visit,0,sizeof(visit)); int wjm=1; for (int i=1;i<=N;i++) { for (int j=1;j<=M;j++) { if (g[i][j]==1) continue; if (visit[i][j]) continue; int flag=1; int animal=0; visit[i][j]=1; if (g[i][j]==2) animal++; q.push({i,j}); while (!q.empty()) { node u=q.front(); q.pop(); for (int k=0;k<4;k++) { int tx=u.x+X[k]; int ty=u.y+Y[k]; if (g[tx][ty]==1) continue; if (visit[tx][ty]==1) continue; if (judge(tx,ty)==-1) { flag=0; continue; } if (g[tx][ty]==2) animal++; if (animal>=2) wjm=0; visit[tx][ty]=1; q.push({tx,ty}); } } if (flag) hole++; } } if (wjm==0) hole=-1; } void dfs (int x,int y) { Node[cnt].x=x; Node[cnt].y=y; cnt++; g[x][y]=1; ans=ans|(1LL<<(x*M+y-1)); if (st.count(ans)) { cnt--; g[x][y]=0; ans=ans&~(1LL<<(x*M+y-1)); return; } st.insert (ans); if (cnt==K) { hole=0; bfs (); if (hole==H) result++; cnt--; g[x][y]=0; ans=ans&~(1LL<<(x*M+y-1)); return; } for (int i=cnt-1;i>=0;i--) { for (int k=0;k<4;k++) { int tx=Node[i].x+X[k]; int ty=Node[i].y+Y[k]; if (judge(tx,ty)==1) dfs (tx,ty); } } cnt--; g[x][y]=0; ans=ans&~(1LL<<(x*M+y-1)); } int main () { scanf ("%d %d %d %d",&N,&M,&K,&H); for (int i=1;i<=N;i++) cin>>s[i]; for (int i=1;i<=N;i++) { for (int j=0;j<M;j++) { if (s[i][j]=='.') g[i][j+1]=0; else g[i][j+1]=2; } } for (int i=1;i<=N;i++) { for (int j=1;j<=M;j++) { if (!g[i][j]) dfs(i,j); } } printf ("%d ",result); return 0; }