【ICPC-192】uva 167 - The Sultan's Successors

点击打开链接

 

题目意思:给定8 x 8的一个方格,对于该方格来说每一行上面只能取一个数,然后同行同列同对角线上都是不满足,求出所能得到的最大值

 

解题思路:8皇后的变形问题,变为求解所有方案数中的最大的和。我们先分序一下,该解空间的结构,由于每一行只能取一,那么我么就可以知道每一行对应的是解空间的一层,那么我么就可以去搜索这个解空间状态树,从第一行开始搜索,如果行数大于8就return,比较最大的值,在搜索函数里面我们用一个for循环枚举每一列,求出满足条件的一列,通过judge函数去判断,只要判断上面和左边和对角线满足即可,因为后面还不知道,这样就能够遍历整个解空间。

 

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <list>
#include <vector>
#include <stack>
#include <algorithm>
using namespace std;
const int MAXN = 9;

int k, ans;
int val[MAXN][MAXN];
int vis[MAXN][MAXN];


//判断函数
int judge(int x, int y) {
    int i, j;
    //上方向
    for (i = x - 1; i >= 1; i--) {
        if (vis[i][y])
            return 0;
    }
    //左方向
    for (i = y - 1; i >= 1; i--) {
        if (vis[x][i])
            return 0;
    }
    //对角线
    for (i = 1; i <= 8; i++) {
        for (j = 1; j <= 8; j++) {
            if (abs(i - x) == abs(j - y)) {//判断对角线的条件
                if (vis[i][j])
                    return 0;
            }
        }
    }
    return 1;
}

//深搜回溯求解
void dfs(int i , int max) {
    if(i > 8){//如果大于8那么直接更新最大值然后return
       if (max > ans)
           ans = max;
       return;
    }
    for(int j = 1 ; j <= 8 ; j++){//这一行遍历过去找到满足的点
       if (vis[i][j] == 0 && judge(i, j)) {
           vis[i][j] = 1;
           dfs(i + 1 , max + val[i][j]);//递归到下一行
           vis[i][j] = 0;//状态的回溯
       }
    }
}

//主函数
int main() {
    int i, j;
    scanf("%d", &k);
    while (k--) {
        memset(val, 0, sizeof (val));
        memset(vis, 0, sizeof (vis));
        for (i = 1; i <= 8; i++) {
            for (j = 1; j <= 8; j++)
                scanf("%d", &val[i][j]);
        }
        ans = 0;
        dfs(1 , 0);
        printf("%5d\n", ans);
    }
}

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值