【福建集训】深度优先搜索(1/3)
A.铺地板题
只要你思路足够怪就难以被卡

我们将问题简化,事实上对于一个格子只能有两种决策,一种是向右扩展,一种是向下扩展,如果一个格子是被扩展的格子那么它肯定不可以再向外扩展了
具体内容回头补充
#include<bits/stdc++.h> using namespace std; #define re register #define fo1(l,r) for(re int i=l;i<=r;++i) #define fo2(l,r) for(re int j=l;j<=r;++j) #define fo3(l,r) for(re int k=l;k<=r;++k) #define fo4(l,r) for(re int tt=l;tt<=r;++tt) #define fo(l) for(re int i=h[l],go;i;i=x[i].last) #define inf 0x3f3f3f3f #define INF 0x7fffffffffffffff #define LL long long #define itn int #define DB double inline int read() { int x=0,f=1;char ch=getchar(); while(!isdigit(ch)) { if(ch=='-') f=-1; ch=getchar(); } while(isdigit(ch)) { x=(x<<3)+(x<<1)+ch-48; ch=getchar(); } return x*f; } int n,m; int a[30][30],ANS; bitset<21> st; inline void dfs(int h,int l,bitset<21> x,bitset<21> y,int cntx,int cnty) { //边界处理 if(h==n+1) { // cout<<"ANS:------------"<<endl; // printf("当前是[%d,%d]",h,l); // cout<<"当前行"<<cntx<<" "; // fo1(1,m-1) // cout<<x[i]; // cout<<"下一行"<<cnty<<" "; // fo1(1,m-1) // cout<<y[i]; // cout<<endl; // cout<<"地图"<<endl; // fo1(1,n) // { // fo2(1,m) // { // cout<<a[i][j]<<" "; // } // cout<<endl; // } ++ANS; return; } // printf("当前是[%d,%d]",h,l); // cout<<"当前行"<<cntx<<" "; // fo1(1,m-1) // cout<<x[i]; // cout<<"下一行"<<cnty<<" "; // fo1(1,m-1) // cout<<y[i]; // cout<<endl; // cout<<"地图"<<endl; // fo1(1,n) // { // fo2(1,m) // { // cout<<a[i][j]<<" "; // } // cout<<endl; // } re bool ty1,ty2;//下面开始判断可行性 if(a[h][l]==0){ty1=1;ty2=1;} else if(a[h][l]==1){ty1=0;ty2=1;} else{ty1=0;ty2=0;}//2表示已经被占有 if(l==m) ty1=0; if(h==n) ty2=0; if(a[h][l+1]==2) ty1=0; // printf("选择可行性%d %d\n",ty1,ty2); if(!ty1 && !ty2 && a[h][l]!=2) return; if(a[h][l]==2) { // cout<<"yes"<<endl; if(l==m) {//开始可行性判断 if(cntx==m-1 || h==1) dfs(h+1,1,y,st,cnty,0); else return; } else dfs(h,l+1,x,y,cntx,cnty); return; } if(ty1) { re bool xx=0,yy=0; if(x[l]==0){x[l]=1;++cntx;xx=1;} if(y[l]==0){y[l]=1;++cnty;yy=1;} re int zz=a[h][l+1];a[h][l+1]=2; if(l==m)//开始可行性判断 { // printf("向右扩展\n"); if(cntx==m-1 || h==1) dfs(h+1,1,y,st,cnty,0); a[h][l+1]=zz;//开始回溯 if(xx==1){x[l]=0;--cntx;} if(yy==1){y[l]=0;--cnty;} } else { // printf("向右扩展\n"); dfs(h,l+1,x,y,cntx,cnty); a[h][l+1]=zz;//开始回溯 if(xx==1){x[l]=0;--cntx;} if(yy==1){y[l]=0;--cnty;} } } if(ty2) { re bool xx=0,yy=0; if(y[l]==0 && l!=m){y[l]=1;++cnty;xx=1;} if(y[l-1]==0 && l!=1){y[l-1]=1;++cnty;yy=1;} re int zz=a[h+1][l];a[h+1][l]=2; // int ww=0; // if(a[h+1][l-1]!=2){ww=a[h+1][l-1];a[h+1][l-1]=1;} if(l==m)//开始可行性判断 { // printf("向下扩展\n"); if(cntx==m-1 || h==1) dfs(h+1,1,y,st,cnty,0); if(xx==1){y[l]=0;--cnty;} if(yy==1){y[l-1]=0;--cnty;} a[h+1][l]=zz; // if(ww!=0) // a[h+1][l-1]=ww; } else { // printf("向下扩展\n"); dfs(h,l+1,x,y,cntx,cnty); if(xx==1){y[l]=0;--cnty;} if(yy==1){y[l-1]=0;--cnty;} a[h+1][l]=zz; // if(ww!=0) // a[h+1][l-1]=ww; } } return; } int main() { freopen("floor.in","r",stdin); freopen("floor.out","w",stdout); n=read();m=read(); if(n*m%2==1) { printf("0"); return 0; } dfs(1,1,st,st,0,0); printf("%d",ANS); fclose(stdin); fclose(stdout); return 0; }

浙公网安备 33010602011771号