Problem I. 马的指派

原题:

题意:

n*m的棋盘用最少个马管住(放马的位置,马可以打到的位置),问这个数量。

解析:

dfs,每个位置三种状态:

  • 0:可以放置
  • 1:不可放置
  • 2:已经放置

主要是别马脚的问题,如果有个点没有被放置,它需要被另一个点管住,那么这个路上不能有马脚。

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(register int i=a;i<=b;i++)

int read(){ int ans=0; char last=' ',ch=getchar();
while(ch<'0' || ch>'9')last=ch,ch=getchar();
while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
if(last=='-')ans=-ans; return ans;
}

int Map[6][6];
int n,m;
int di[8][2]={{1,2},{1,-2},{-1,2},{-1,-2},{2,1},{-2,-1},{-2,1},{2,-1}};
int dii[8][2]={{1,1},{1,-1},{-1,1},{-1,-1},{1,1},{-1,-1},{-1,1},{1,-1}};
int ans;
void out(){
    printf("out\n");
    rep(i,1,n){
        rep(j,1,m){
            printf("%d ",Map[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}
void dfs(const int x,const int y,int use){
    if(use>=ans)return;
    if(x>n){if(ans>use)ans=use;return;}
    if(Map[x][y]==2)
        return dfs((y==m?x+1:x),(y==m?1:y+1),use);
    if(Map[x][y]==0){
        // 填
        Map[x][y]=2;
        dfs((y==m?x+1:x),(y==m?1:y+1),use+1);
        Map[x][y]=0;
    }
    // 不填
    int can=0;
    rep(i,0,7){
        int xx=x+di[i][0],yy=y+di[i][1];
        int jx=x+dii[i][0],jy=y+dii[i][1];
        if(xx<1||xx>n||yy<1||yy>m||Map[xx][yy]!=2||Map[jx][jy]==2)continue;
        can=1;
        int tmp=Map[jx][jy];
        Map[jx][jy]=1;
        dfs((y==m?x+1:x),(y==m?1:y+1),use);
        Map[jx][jy]=tmp;
    }
    if(can)return;
    rep(i,0,7){
        int xx=x+di[i][0],yy=y+di[i][1];
        int jx=x+dii[i][0],jy=y+dii[i][1];
        if(xx<1||xx>n||yy<1||yy>m||Map[jx][jy]==2)continue;
        //被限制或已填
        if(Map[xx][yy])continue;
        Map[xx][yy]=2;
        int tmp=Map[jx][jy];
        Map[jx][jy]=1;
        dfs((y==m?x+1:x),(y==m?1:y+1),use+1);
        Map[xx][yy]=0;
        Map[jx][jy]=tmp;
    }
}

int Ans[6][6];
int main(){
    int t=read();
    while(t--){
        n=read(),m=read();
        if(Ans[n][m]){
            printf("%d\n",Ans[n][m]);
            continue;
        }
        memset(Map,0,sizeof Map);
        ans=1e9;
        dfs(1,1,0);
        Ans[n][m]=ans;
        printf("%d\n",ans);
    }
}

猜你喜欢

转载自blog.csdn.net/jk_chen_acmer/article/details/88079065
今日推荐