版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhaohaibo_/article/details/86655493
题目描述
小a正在玩一款星际探索游戏,小a需要驾驶着飞船从1号星球出发前往n号星球。其中每个星球有一个能量指数p。星球i能到达星球j当且仅当
。
同时小a的飞船还有一个耐久度t,初始时为1号点的能量指数,若小a前往星球j,那么飞船的耐久度会变为
(即
异或
,关于其定义请自行百度)
小a想知道到达n号星球时耐久度最大为多少.
注意:对于每个位置来说,从它出发可以到达的位置仅与两者的p有关,与下标无关
输入描述:
第一行一个整数n,表示星球数
接下来一行有n个整数,第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
备注:
题意:
给定一些数,挑出一些数使异或和最大,最后异或的数需要是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;
}