牛客寒假算法基础集训营1 小a与星际探索

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhaohaibo_/article/details/86655493

题目描述
小a正在玩一款星际探索游戏,小a需要驾驶着飞船从1号星球出发前往n号星球。其中每个星球有一个能量指数p。星球i能到达星球j当且仅当 p i > p j p_i>p_j
同时小a的飞船还有一个耐久度t,初始时为1号点的能量指数,若小a前往星球j,那么飞船的耐久度会变为 t p j t⊕p_j (即 t t 异或 p j p_j ,关于其定义请自行百度)
小a想知道到达n号星球时耐久度最大为多少.
注意:对于每个位置来说,从它出发可以到达的位置仅与两者的p有关,与下标无关

输入描述:
第一行一个整数n,表示星球数
接下来一行有n个整数,第i个整数表示 p i p_i

输出描述:
一个整数表示到达n号星球时最大的耐久度
若不能到达n号星球或到达时的最大耐久度为0则输出−1

示例
输入

3
457 456 23

输出

478

说明
小a有两种方法到达3号星球
第一种:1→2→3,最终耐久度为457⊕456⊕23=22
第二种:1→3,最终耐久度为457⊕23=478

输入

4
2 4 4 2

输出

-1

输入

5
234 233 123 2333 23

输出

253

备注: 1 n , p i 3000 1⩽n,∀p_i⩽3000


题意:
给定一些数,挑出一些数使异或和最大,最后异或的数需要是a[n]

高斯消元

最多有3000个数,每个数二进制表示最多15位
把每个二进制数看作一个向量,向量最大独立集个数等于向量的列数,最多只有15个向量独立。

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

typedef long long ll;
const int N = 3010;
int n, p[N];

int main()
{
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> p[i];

    if (n == 1)
        cout << (p[0] ? p[0] : -1) << endl;
    else if (p[0] <= p[n - 1])
        cout << -1 << endl;
    else
    {
        vector<int> sets;
        for (int i = 1; i < n - 1; i++)
            if (p[i] < p[0] && p[i] > p[n - 1])
            {
                sets.push_back(p[i]);
            }
        if (sets.size())
        {
            for (int i = 14, k = 0; i >= 0; i -- )
            {
                for (int j = k; j < sets.size(); j ++ )
                    if (sets[j] >> i && 1)
                    {
                        swap(sets[j], sets[k]);
                        break;
                    }
                if (sets[k] >> i & 1)
                {
                    for (int j = k + 1; j < sets.size(); j ++ )
                        if (sets[j] >> i & 1)
                            sets[j] ^= sets[k];
                    k ++;
                }
            }
        }

        int res = p[0] ^ p[n - 1];
        if (sets.size())
        {
            for (int i = 14, k = 0; i >= 0; i -- )
            {
                if (sets[k] >> i & 1)
                {
                    if (!(res >> i & 1)) res ^= sets[k];
                    k ++ ;
                }
            }
        }
        if (!res) res = -1;
        cout << res << endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zhaohaibo_/article/details/86655493