【福建集训】深度优先搜索(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;
}

 

posted @ 2023-07-22 21:07  小鱼儿吼吼  阅读(8)  评论(0)    收藏  举报