UVA - 639 Don't Get Rooked

12 篇文章 0 订阅

题目大意:类似于八皇后。每行每列只能放一个位置,若有墙隔着就互不影响,问最多能放几个。

解题思路:回溯,先读入地图,ok() 分上下左右四个方向判断当前位置是否可以放置,ans 保存最佳答案。tmp 是当前放了多少个。遍历地图,若当前位置可放就标记一下,个数 ++,递归后还原状态。

#include<iostream> 
#include<cstdio>
#include<cmath>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
char map[5][5];
bool vis[5][5];
int n, ans, tmp;
bool ok(int r, int c) {     
    int up, down, lef, rig;
    up = down = lef = rig = 1;
    for (int i = 0; i < r; i++) {
        if (vis[i][c]) up = 0;
        else if (map[i][c] == 'X') up = 1;
    }
    for (int i = r+1; i < n; i++) {
        if (vis[i][c]) down = 0;
        else if (map[i][c] == 'X') down = 1;
    }
    for (int i = 0; i < c; i++) {
        if (vis[r][i]) lef = 0;
        else if (map[r][i] == 'X') lef = 1;
    }
    for (int i = c+1; i < n; i++) {
        if (vis[r][i]) rig = 0;
        else if (map[r][i] == 'X') rig = 1;
    }
    if (up && down && lef && rig && !vis[r][c] && map[r][c] != 'X') return true;
    else return false;
}
void search(int r, int c) {
    if (c == n) { r++; c = 0;}
    if (r == n) {
        if (tmp > ans) ans = tmp;
        return;
    }
    for (int i = r; i < n; i++)
        for (int j = c; j < n; j++) {
            int t = tmp;
            if (ok(i, j)) {
                tmp++;
                vis[i][j] = 1;
            }
                search(i,j+1);
                tmp = t;
                vis[i][j] = 0;
    }
}
int main() {
    while (scanf("%d", &n) != EOF && n) {
        memset(vis, 0, sizeof(vis));
        for (int i = 0; i < n; i++)
            scanf("%s", map[i]);

        ans = 0;
        tmp = 0;
        search(0, 0);

        printf("%d\n", ans);
    }
return 0; 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值