HDU 4499.Cannon 搜索

Cannon

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 965    Accepted Submission(s): 556

Problem Description

In Chinese Chess, there is one kind of powerful chessmen called Cannon. It can move horizontally or vertically along the chess grid. At each move, it can either simply move to another empty cell in the same line without any other chessman along the route or perform an eat action. The eat action, however, is the main concern in this problem. 
An eat action, for example, Cannon A eating chessman B, requires two conditions: 
1、A and B is in either the same row or the same column in the chess grid. 
2、There is exactly one chessman between A and B. 
Here comes the problem. 
Given an N x M chess grid, with some existing chessmen on it, you need put maximum cannon pieces into the grid, satisfying that any two cannons are not able to eat each other. It is worth nothing that we only account the cannon pieces you put in the grid, and no two pieces shares the same cell.

Input

There are multiple test cases. 
In each test case, there are three positive integers N, M and Q (1<= N, M<=5, 0<=Q <= N x M) in the first line, indicating the row number, column number of the grid, and the number of the existing chessmen. 
In the second line, there are Q pairs of integers. Each pair of integers X, Y indicates the row index and the column index of the piece. Row indexes are numbered from 0 to N-1, and column indexes are numbered from 0 to M-1. It guarantees no pieces share the same cell.

Output

There is only one line for each test case, containing the maximum number of cannons.

Sample Input

4 4 2

1 1 1 2

5 5 8

0 0 1 0 1 1 2 0 2 3 3 1 3 2 4 0

Sample Output

8

9

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4499

题意:在n×m的棋盘上面有Q的棋子,它们之间不可以相互吃对方。现在要在棋盘上面增加棋子“炮”,问最多可以增加多少个炮使得炮之间不能相互吃对方(1<= N, M<=5, 0<=Q <= N x M)。炮a吃棋子b的规则是,a和b在一行或者一列,a和b之间有一个棋子。

思路:n和m很小,直接暴力BFS搜索。注意炮可以增加的规则。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m;
int ans=0;
int edge[10][10];
int dfs(int x,int y,int cou)
{
    int i,j,t,sign,ok;
/*
    for(i=0; i<n; i++)
    {
        for(j=0; j<m; j++)
            cout<<edge[i][j]<<" ";
        cout<<endl;
    }
    cout<<endl;
*/
    if(cou>ans) ans=cou;
    edge[x][y]=2;
    /**当前行可以增加*/
    for(j=y+1; j<n; j++)
    {
        if(edge[x][j]==1) continue;
        sign=0;
        ok=1;
        for(t=j-1; t>=0; t--)
        {
            if(edge[x][t]!=0) sign++;
            if(sign==2&&edge[x][t]==2)
            {
                ok=0;
                break;
            }
        }
        if(ok==1)
        {
            sign=0;
            for(t=x-1; t>=0; t--)
            {
                if(edge[t][j]!=0) sign++;
                if(sign==2&&edge[t][j]==2)
                {
                    ok=0;
                    break;
                }
            }
            if(ok==1)
            {
                edge[x][j]=2;
                dfs(x,j,cou+1);
                edge[x][j]=0;
            }
        }
    }
    /**当前行不能增加,加入后面的行*/
    for(i=x+1; i<n; i++)
    {
        for(j=0; j<m; j++)
        {
            if(edge[i][j]==1) continue;
            sign=0;
            ok=1;
            for(t=i-1; t>=0; t--)
            {
                if(edge[t][j]!=0) sign++;
                if(sign==2&&edge[t][j]==2)
                {
                    ok=0;
                    break;
                }
            }
            if(ok==1)
            {
                edge[i][j]=2;
                dfs(i,j,cou+1);
                edge[i][j]=0;
            }
        }
    }
}
int main()
{
    int i,j,q;
    int x,y;
    while(scanf("%d%d%d",&n,&m,&q)!=EOF)
    {
        memset(edge,0,sizeof(edge));
        while(q--)
        {
            scanf("%d%d",&x,&y);
            edge[x][y]=1;
        }
        ans=0;
        for(i=0; i<n; i++)
            for(j=0; j<m; j++)
                if(edge[i][j]==0)
                {
                    edge[i][j]=2;
                    dfs(i,j,1);
                    edge[i][j]=0;
                }
        cout<<ans<<endl;
    }
    return 0;
}

时间: 2024-10-07 15:25:15

HDU 4499.Cannon 搜索的相关文章

HDU 4499 Cannon (暴力搜索)

题意:在n*m的方格里有t个棋子,问最多能放多少个炮且每个炮不能互相攻击(炮吃炮) 炮吃炮:在同一行或同一列且中间有一颗棋子. #include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> #include <queue> #include <math.h> #define M 50 #define LL long long using

hdu 4499 Cannon(暴力)

题目链接:hdu 4499 Cannon 题目大意:给出一个n*m的棋盘,上面已经存在了k个棋子,给出棋子的位置,然后求能够在这种棋盘上放多少个炮,要求后放置上去的炮相互之间不能攻击. 解题思路:枚举行放的情况,用二进制数表示,每次放之前推断能否放下(会不会和已经存在的棋子冲突),放下后推断会不会互相攻击的炮,仅仅须要对每一个新加入的炮考虑左边以及上边就能够了. #include <cstdio> #include <cstring> #include <algorithm&

hdu 4499 Cannon 暴力dfs搜索

Cannon Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 589    Accepted Submission(s): 338 Problem Description In Chinese Chess, there is one kind of powerful chessmen called Cannon. It can move

hdu 4499 Cannon dfs

Cannon Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4499 Description In Chinese Chess, there is one kind of powerful chessmen called Cannon. It can move horizontally or vertically along the chess grid. At eac

HDU 4499 Cannon (暴力求解)

题意:给定一个n*m个棋盘,放上一些棋子,问你最多能放几个炮(中国象棋中的炮). 析:其实很简单,因为棋盘才是5*5最大,那么直接暴力就行,可以看成一行,很水,时间很短,才62ms. 代码如下: #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <iostream> #include <cstring> #include &

HDU 4499 Cannon

题意: 思路: #include<cstdio> #include<iostream> #include<cstring> #include<cmath> #include<stdlib.h> #include<vector> #include<queue> #include<stack> #include<algorithm> using namespace std; const int MAXN

HDU 2828 DLX搜索

Lamp Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 771    Accepted Submission(s): 230 Special Judge Problem Description There are several switches and lamps in the room, however, the connecti

HDU 1518 Square 搜索

Square Time Limit : 10000/5000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submission(s) : 11   Accepted Submission(s) : 5 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description Given a set of sticks of vario

HDU ACM 4499 Cannon 暴力DFS

分析:N和M很小,直接暴力搜索即可. #include<iostream> using namespace std; #define N 6 #define M 6 int vis[N][M]; //有炮设为2,无炮为0,其他为1 int n,m,q,ans; #define max(a,b) ((a)>(b)?(a):(b)) bool Valid(int i,int j) //只需要判断当前和前面的即可(行列) { int fg=0; int k; if(vis[i][j]==1)