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

HINT

题意

在一个象棋棋盘上放炮,要求两个炮不能互相打到,然后问你最多能放几个炮

题解:

直接dfs就好了,范围很小

代码:

//qscqesze
#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <typeinfo>
#include <fstream>
#include <map>
#include <stack>
typedef long long ll;
using namespace std;
//freopen("D.in","r",stdin);
//freopen("D.out","w",stdout);
#define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
#define test freopen("test.txt","r",stdin)
#define maxn 2000001
#define mod 10007
#define eps 1e-9
int Num;
char CH[20];
const int inf=0x3f3f3f3f;
const ll infll = 0x3f3f3f3f3f3f3f3fLL;
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
inline void P(int x)
{
    Num=0;if(!x){putchar(‘0‘);puts("");return;}
    while(x>0)CH[++Num]=x%10,x/=10;
    while(Num)putchar(CH[Num--]+48);
    puts("");
}
//**************************************************************************************

int a[30],b[30],visit[7][7],n,m,q,ans;
void dfs(int x,int y,int cnt)//一行一行地搜索,直到找到最后一行时结束时记录最大值
{
    if(x>=n){
        ans=max(ans,cnt);
        return;
    }
    if(y>=m){
        dfs(x+1,0,cnt);
        return;
    }
    if(visit[x][y]){
        dfs(x,y+1,cnt);
        return;
    }
    dfs(x,y+1,cnt);
    int t,flag=0;
    for(t=y-1;t>=0;t--)
        if(visit[x][t]) break;
    for(int i=t-1;i>=0;i--)
    {
        if(visit[x][i]==2) {flag=1;break;}
        if(visit[x][i]) break;
    }
    if(flag)return;//判断这一列上是否存在炮互吃
    for(t=x-1;t>=0;t--)
        if(visit[t][y]) break;
    for(int i=t-1;i>=0;i--){
        if(visit[i][y]==2) {flag=1;break;}
        if(visit[i][y]) break;
    }
    if(flag) return;//判断这一行上是否存在炮互吃
    visit[x][y]=2;
    dfs(x,y+1,cnt+1);
    visit[x][y]=0;//回溯
}
int main()
{
    while(scanf("%d%d%d",&n,&m,&q)!=EOF){
        memset(visit,0,sizeof(visit));
        for(int i=0;i<q;i++){
            scanf("%d%d",&a[i],&b[i]);
            visit[a[i]][b[i]]=1;
        }
        ans=0;
        dfs(0,0,0);
        printf("%d\n",ans);
    }
    return 0;
}
时间: 2024-12-14 18:40:55

hdu 4499 Cannon dfs的相关文章

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 搜索

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

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

HDU4499 Cannon DFS 回溯的应用

题意就是给你一个n*m的棋盘,然后上面已经有了 棋子,并给出这些棋子的坐标,但是这些棋子是死的就是不能动,然后让你在棋盘上面摆炮,但是炮之间不能互相吃,吃的规则我们斗懂得 炮隔山打嘛,问你最多能放几个炮 肯定是搜索了,n,m最大才5,可能挺久没做了,对于回溯反而把握不好了,写了好久调试了好久,才过 #include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> #

HDU 4921 Map DFS+状态压缩+乘法计数

算最多十条链,能截取某前缀段,每种方案都可以算出一个权值,每种方案的概率都是总数分之一,问最后能构成的所有可能方案数. 对计数原理不太敏感,知道是DFS先把链求出来,但是想怎么统计方案的时候想了好久,其实因为只能取某个链的前缀,所以直接取链长加+1 然后相乘即可,当然因为会出现都是空的那种情况,要去掉,全部乘完之后,要-1 然后就是算权值了,权值等于当前加进来的点的总和 以及 等级相同的点的加成,并不是特别好算,这时候考虑每个状态下的点对全局的贡献,对,就是这个思想,用状态压缩来表示状态,然后这

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)