Click to open link
Test instructions: Place a bomb at a point where the bomb can be blown to infinity and is the form of a cross, but if it blows to # or * then stops in this direction, ask how many bombs are needed at least and detonate to blow up all the #
Idea: A template dance chain, for the building we will all the # as a column, and then all the point is the place to put the bomb as a row, and then find each point can be fried # on it, after the building to run a dance chain can be repeated template can be
#include <vector> #include <stdio.h> #include <string.h> #include <stdlib.h> #include < Iostream> #include <algorithm>using namespace std;typedef long long ll;typedef unsigned long long ull;const int in f=0x3f3f3f3f;const ll Inf=0x3f3f3f3f3f3f3f3fll;const int Maxn=230;int L[MAXN*MAXN],R[MAXN*MAXN],U[MAXN*MAXN],D[MAXN *maxn];//nodes up and down four-way linked list int c[maxn*maxn],h[maxn],cnt[maxn],vis[maxn];//c column H row CNT list number of elements int n,m,id,fans;void init ( int lll) {for (int i=0;i<=lll;i++) {cnt[i]=0; U[i]=d[i]=i; L[i+1]=i; r[i]=i+1; } r[lll]=0;id=lll+1; memset (h,-1,sizeof (H)); void Link (int r,int c) {cnt[c]++; C[id]=c; U[ID]=U[C];D [U[c]]=id; D[id]=c; U[c]=id; if (h[r]==-1) H[r]=l[id]=r[id]=id; else{L[id]=l[h[r]]; R[l[h[r]]]=id; R[ID]=H[R]; L[h[r]]=id; } id++;} void Remove (int Size) {for (int j=d[size];j!=size;j=d[j]) l[r[j]]=l[j],r[l[j]]=r[j];} void Resume (int Size) {for (int j=d[size];j!=size;j=d[j]) l[r[j]]=r[l[j]]=j;} int h () {int sum=0; memset (vis,0,sizeof (VIS)); for (int i=r[0];i;i=r[i]) {if (vis[i]) continue; sum++; For (int. J=d[i];j!=i;j=d[j]) {for (int k=r[j];k!=j;k=r[k]) vis[c[k]]=1; }} return sum;} void Dance (int k) {int mm=maxn,pos; if (K+h () >=fans) return; if (! R[0]) {if (K<fans) fans=k; Return } for (int i=r[0];i;i=r[i]) if (mm>cnt[i]) mm=cnt[i],pos=i; for (int i=d[pos];i!=pos;i=d[i]) {Remove (i); for (int j=r[i];j!=i;j=r[j]) Remove (j); Dance (k+1); for (int j=r[i];j!=i;j=r[j]) Resume (j); Resume (i); }}char str[20][20];int A[20][20];int Main () {int n,m; while (scanf ("%d%d", &n,&m)!=-1) {for (int i=0;i<n;i++) scanf ("%s", Str[i]); int kk=0,kkk=1; for (int i=0;i<n;i++) {for (int j=0;j<m;j++) {if (str[i][j]== ' # ') a[i][j]= (++KK); }} init (KK); for (int i=0;i<n;i++) {for (int j=0;j<m;j++) {if (str[i][j]== '. ') {int ii,jj; Ii=i;jj=j; while (ii>1) {if (str[ii-1][jj]== ' * ') is break; if (str[ii-1][jj]== ' # ') {Link (KKK,A[II-1][JJ]); }ii--; } ii=i;jj=j; while (ii<n-1) {if (str[ii+1][jj]== ' * ') is break; if (str[ii+1][jj]== ' # ') {Link (KKK,A[II+1][JJ]); }ii++; } ii=i;jj=j; while (jj>1) {if (str[ii][jj-1]== ' * ') is break; if (str[ii][jj-1]== ' # ') {Link (kkk,a[ii][jj-1]); }jj--; } ii=i;jj=j; while (jj<m-1) { if (str[ii][jj+1]== ' * ') break; if (str[ii][jj+1]== ' # ') {Link (kkk,a[ii][jj+1]); }jj++; } kkk++; }}} fans=kkk-1; Dance (0); printf ("%d\n", fans); } return 0;}
HDU 3529 Dance chain repeatable overlay