newcoder 筱玛的迷阵探险(搜索 + 01字典树)题解

题目描述

筱玛是个快乐的男孩子。
寒假终于到了,筱玛决定请他的朋友们一起来玩迷阵探险。
迷阵可以看做一个n×nn×n的矩阵A,每个格子上有一个有一个数Ai,j
入口在左上角的(1,1)处,出口在右下角的(n,n)处。每一步都只能向下或向右移动一格。最后能获得的经验值为初始经验e与路径上经过的所有数的权值异或和。
求筱玛最大可能获得的经验值。

输入描述:

第一行两个整数n和e。
接下来n行,每行n个整数,描述矩阵A。

输出描述:

一个整数,表示筱玛最大可能获得的经验值。
示例1

输入

复制
5 2
3 4 7 2 6
3 5 2 9 0
3 8 5 7 3
2 5 3 1 4
9 8 6 3 5

输出

复制
15

链接:https://ac.nowcoder.com/acm/contest/545/D

思路:显然我们直接搜等于是在搜一颗二叉树,复杂度O(2^40)左右,肯定超时。但是我们可以用其他方法搜,先从左上角搜,,搜到对角线,然后把所有答案保存在01字典树里。再从右下角往回搜,遇到对角线直接在字典树搜最大异或,取最大值。

代码:

#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include <iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 20 + 10;
const int INF = 0x3f3f3f3f;
struct node{
    node* Next[2];
    node(){
        for(int i = 0; i < 2; i++)
           Next[i] = NULL;
    }
};
node* e[maxn];  //走到对角线(含)
int mp[maxn][maxn];
int n, s;
void add(int x, int pos){
    node* a = e[pos];
    for(int i = 31; i >=0; i--){
        int v = (x >> i) & 1;
        if(a ->Next[v] == NULL)
            a ->Next[v] = new node();
        a = a ->Next[v];
    }
}
int query(int x, int pos){
    node* a = e[pos];
    int ret = 0;
    for(int i = 31; i >= 0; i--){
        int v = (x >> i) & 1;
        if(a ->Next[!v] != NULL){
            a = a ->Next[!v];
            ret += (1 << i);
        }
        else a = a ->Next[v];
    }
    return ret;
}
void dfs(int x, int y, int sum){
    if(x + y == n + 1){
        add(sum ^ mp[x][y], x);
        return;
    }
    dfs(x + 1, y, sum ^ mp[x][y]);
    dfs(x, y + 1, sum ^ mp[x][y]);
}
int Max;
void dfsBack(int x, int y, int sum){
    if(x + y == n + 1){
        Max = max(query(sum, x), Max);
        return;
    }
    dfsBack(x - 1, y, sum ^ mp[x][y]);
    dfsBack(x, y - 1, sum ^ mp[x][y]);
}
int main(){
    scanf("%d%d", &n, &s);
    for(int i = 1; i <= n; i++){
        e[i] = new node();
        for(int j = 1; j <= n; j++){
            scanf("%d", &mp[i][j]);
        }
    }
    dfs(1, 1, s);
    Max = -1;
    dfsBack(n, n, 0);
    printf("%d
", Max);
    return 0;
}
原文地址:https://www.cnblogs.com/KirinSB/p/10627859.html