zoukankan      html  css  js  c++  java
  • 字典树+折半+贪心--牛客练习赛37 C 筱玛的迷阵探险

    牛客练习赛37 C 筱玛的迷阵探险

    参考博客

    链接:

    https://ac.nowcoder.com/acm/contest/342/C

    来源:牛客网

    题目描述

    筱玛是个快乐的男孩子。
    寒假终于到了,筱玛决定请他的朋友们一起来玩迷阵探险。
    迷阵可以看做一个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
    

    备注:

    1≤n≤20;0≤e,Ai,j<231
    

    思路

    折半,字典树。

    从左上角遍历到对角线停止,用字典树存对角上每个点的所有可能值。

    再从右下角往对角线遍历,到对角线时,贪心找字典树上每位数都为1的值,再异或算答案

    有人说注意字典树大小

    代码

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <cmath>
    #include <sstream>
    #include <algorithm>
    #include <set>
    #include <map>
    #include <vector>
    #include <queue>
    #include <iomanip>
    #include <stack>
    
    using namespace std;
    
    typedef long long LL;
    const int INF = 0x3f3f3f3f;
    const int N = 5e6 + 50;
    const int MOD = 1e9 + 9;
    
    #define lson l, m, rt << 14
    #define rson m + 1, r, rt << 1 | 1
    #define F(i, l, r) for(int i = l;i <= (r);++i)
    #define RF(i, l, r) for(int i = l;i >= (r);--i)
    
    int n;
    LL mp[30][30], ans, e;
    int tree[30][N][2], cnt;
    
    void Add(int id, LL num)
    {
        int rt = 0;
        RF(i, 30, 0)
        {
            int t = (num >> i) & 1;
            if(!tree[id][rt][t]) tree[id][rt][t] = ++cnt;//这里写成cnt++就错了,注意字典树模板
            rt = tree[id][rt][t];
        }
    }
    
    LL solve(int id, LL num)
    {
        LL rt = 0, ret = 0;
        RF(i, 30, 0)
        {
            int t = (num >> i) & 1;
            if(tree[id][rt][t ^ 1]) {ret += (1ll << i);rt = tree[id][rt][t ^ 1];}
            else rt = tree[id][rt][t];
        }
        return ret;
    }
    
    void dfs1(int x, int y, LL val)
    {
        if(x + y == n + 1) {Add(x, val ^ mp[x][y]);return ;}
        if(y + 1 <= n) dfs1(x, y + 1, val ^ mp[x][y]);
        if(x + 1 <= n) dfs1(x + 1, y, val ^ mp[x][y]);
    }
    
    void dfs2(int x, int y, LL val)
    {
        if(x + y == n + 1) {ans = max(ans, solve(x, val));return ;}
        if(y - 1 > 0) dfs2(x, y - 1, val ^ mp[x][y]);
        if(x - 1 > 0) dfs2(x - 1, y, val ^ mp[x][y]);
    }
    
    int main()
    {
        cin >> n >> e;
        F(i, 1, n) F(j, 1, n) cin >> mp[i][j];
        dfs1(1, 1, e);dfs2(n, n, 0);
        cout << ans << endl;
        return 0;
    }
    
    
  • 相关阅读:
    C语言printf()输出格式大全
    C语言ASCII码、运算符优先级、转义字符
    通过Navicat for MySQL远程连接的时候报错mysql 1130 的解决方法
    mysql kill process解决死锁
    常用的二种修改mysql最大连接数的方法
    show processlist结果筛选
    数据库连接driverClass和jdbcUrl大全
    在实例中引用模式文档
    在Eclipse中导入dtd和xsd文件,使XML自动提示
    Linux下Java安装与配置
  • 原文地址:https://www.cnblogs.com/shuizhidao/p/10802962.html
Copyright © 2011-2022 走看看