zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    201671010146 2017-2 <表格监督>
    201671010146 2017-2 《Java学期末有感》
    201671010146 2017-2 《Java线程》
    201671010146 2017-2 《第十六周学习Java有感》
    201671010146 2017―2 《第16周学习java有感》
    201671010146 2017―2 《第十五周学习java有感》
    201671010146 2017-2 《java第十一章学习感悟》
    201671010146 2017-2 《第十章学习感悟》
    201671010146 2017―2 《第11周学习java有感》
    201671010146 2017-2 《java第八章学习感悟》
  • 原文地址:https://www.cnblogs.com/KirinSB/p/10627859.html
Copyright © 2011-2022 走看看