小a与星际探索
题目描述:
链接:
https://ac.nowcoder.com/acm/contest/317/C
来源:牛客网
小a正在玩一款星际探索游戏,小a需要驾驶着飞船从1号星球出发前往n号星球。其中每个星球有一个能量指数pi。星球i 能到达 星球j 当且仅当pi>pj。同时小a的飞船还有一个耐久度t,初始时为1号点的能量指数,若小a前往星球j,那么飞船的耐久度会变为t⊕pj(即t异或pj,关于其定义请自行百度)小a想知道到达n号星球时耐久度最大为多少。注意:对于每个位置来说,从它出发可以到达的位置仅与两者的能量指数p有关,与下标无关。
输入:
第一行一个整数n,表示星球数
接下来一行有n个整数,第i个整数表示pi
输出:
一个整数表示到达n号星球时最大的耐久度
若不能到达n号星球或到达时的最大耐久度为0则输出−1
说明:
小a有两种方法到达3号星球
第一种:
1→2→3,最终耐久度为457⊕456⊕23=22
第二种:
1→3,最终耐久度为457⊕23=478
1⩽n,∀pi⩽3000
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=3005;
int main()
{
int n,p[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]);//因为只能到达比当前星球能量指数小的星球,初始星球能量指数为p[0],最终要求到第n个星球(能量指数为p[n-1]),所以中间的星球能量指数一定在p[0]到p[n-1]之间。
}
}
if(sets.size())//这里高斯消元的过程。
{
for(int i=14,k=0;i>=0;i--)//寻找第I位为1的数,让其下标为K;
{
for(int j=k;j<sets.size();j++)
{
if(sets[j]>>i&1)
{
swap(sets[j],sets[k]);
break;
}
}
if(sets[k]>>i&1)//检查后面的数,如果该位上也为1,则让其变为0
{
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;
}
2月14日。