HDU 4499 Cannon

题意:一个棋盘(n*m,0<n,m<=5),放置了Q个棋子,问这个棋盘最多还能放多少炮,使得任意两个炮不能相互吃掉。


分析:n,m<=5。很明显的暴力搜索。这里要注意的一点是两个炮能相互吃掉是只移动一步,即两个炮之间只有一个棋子的情况,而两个炮之间有三个棋子的不算能相互吃掉(因为这样炮要翻两次),而题目并没有说明这点。。。


Code:

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <vector>
#include <queue>
#include <cmath>
#include <map>
#include <set>
#define eps 1e-7
#define LL long long
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;

int Map[7][7];
int n,m,q,ans;


bool OK(int x,int y){//上下左右暴力搜索,检查放在这个位置会不会被吃掉
    int i=y-1;
    int cnt=0;
    while(i>=0){
        if(Map[x][i]==1&&cnt==1) return false;
        if(Map[x][i]==1||Map[x][i]==-1) cnt++;
        i--;
    }
    i=y+1;
    cnt=0;
    while(i<m){
        if(Map[x][i]==1&&cnt==1) return false;
        if(Map[x][i]==1||Map[x][i]==-1) cnt++;
        i++;
    }
    i=x-1;
    cnt=0;
    while(i>=0){
        if(Map[i][y]==1&&cnt==1) return false;
        if(Map[i][y]==1||Map[i][y]==-1) cnt++;
        i--;
    }
    i=x+1;
    cnt=0;
    while(i<n){
        if(Map[i][y]==1&&cnt==1) return false;
        if(Map[i][y]==1||Map[i][y]==-1) cnt++;
        i++;
    }
    return true;
}

void proc(int x,int y,int op,int mark){
    int i=y-1;
    int cnt=0;
    while(i>=0){
        if(Map[x][i]==mark&&cnt==1) Map[x][i]==op;
        if(Map[x][i]==1||Map[x][i]==-1) cnt++;
        i--;
    }
    i=y+1;
    cnt=0;
    while(i<m){
        if(Map[x][i]==mark&&cnt==1) Map[x][i]==op;
        if(Map[x][i]==1||Map[x][i]==-1) cnt++;
        i++;
    }
    i=x-1;
    cnt=0;
    while(i>=0){
        if(Map[i][y]==mark&&cnt==1) Map[i][y]==op;
        if(Map[i][y]==1||Map[i][y]==-1) cnt++;
        i--;
    }
    i=x+1;
    cnt=0;
    while(i<n){
        if(Map[i][y]==mark&&cnt==1) Map[i][y]==op;
        if(Map[i][y]==1||Map[i][y]==-1) cnt++;
        i++;
    }
}

void dfs(int x,int y,int cnt){
    if(cnt>ans) ans=cnt;
    for(int i=x;i<n;i++){
        for(int j=0;j<m;j++){
            if(i==x&&j<y) continue;
            if(!Map[i][j]&&OK(i,j)){
                proc(i,j,2,0);//将放置在(i,j)位置上的炮所能影响的位置处理一下,算是一个剪枝。(其实不加这个剪枝可以跑的更快= =|||)
                Map[i][j]=1;
                dfs(i,j,cnt+1);
                Map[i][j]=0;
                proc(i,j,0,2);
            }
        }
    }
}

int main()
{
    while(scanf("%d %d %d",&n,&m,&q)==3){
        memset(Map,0,sizeof(Map));
        int x,y;
        while(q--){
            scanf("%d %d",&x,&y);
            Map[x][y]=-1;
        }
        ans=0;
        dfs(0,0,0);
        printf("%d\n",ans);
    }
    return 0;
}


你可能感兴趣的:(HDU 4499 Cannon)