HDU 4499 Cannon(回溯)

题目链接:HDU 4499 Cannon

回溯。

这题写了好久,其实刚开始就想错了。开始一直想的是每一行或者每一列最多只能有两个炮,但是这是在那一行或者那一列上只有炮存在的情况下。如果有别的棋子存在,每一行的炮数就没有上限了(假设格子数没有上限),比如这种情况:炮 其他 其他 其他 炮 炮。这种情况就是有三个炮。

后来还想复杂了,我想的是炮可以先吃掉其他棋子,然后在这个新位置再攻击其他的炮,这题应该是不考虑这种情况的。

太久不写回溯手都生了。

#include <iostream>
#include <cstring>
#include <stdio.h>

using namespace std;
const int MAX_N = 5 + 2;
int vis[MAX_N][MAX_N];
int n, m, q, _max;

bool decide(int i, int j)
{
    int flag = 0;
    if(vis[i][j] == 1)
        return false;
    for(int k = i - 1; k >= 0; k--)
    {
        if(vis[k][j] == 1)
            flag++;
        else if(vis[k][j] == 2)
        {
            if(flag == 1)
                return false;
            else
                flag++;
        }
    }
    flag = 0;
    for(int k = j - 1; k >= 0; k--)
    {
        if(vis[i][k] == 1)
            flag++;
        else if(vis[i][k] == 2)
        {
            if(flag == 1)
                return false;
            else
                flag++;
        }
    }
	return true;
}
void dfs(int cnt, int x, int y)
{
    for(int i = x; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            if(x == i && j < y)
                continue;
            if(decide(i, j))
            {
                vis[i][j] = 2;
                dfs(cnt + 1, i, j + 1);
                vis[i][j] = 0;
            }
        }
    }
    _max = max(_max, cnt);
}
int main()
{
    while(scanf("%d%d%d", &n, &m, &q) != EOF)
    {
        int a, b;
        _max = 0;
        memset(vis, 0, sizeof(vis));
        for(int i = 0; i < q; i++)
        {
            scanf("%d%d", &a, &b);
            vis[a][b] = 1;
        }
        dfs(0, 0, 0);
        cout << _max << endl;
    }
    return 0;
}



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