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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章