链接
https://codeforces.com/contest/1205/problem/B
题解
如果有三个数字都再同一位上出现了111,那么这三个点构成了环,答案就为333
一共就有606060个可能用到的二进制位
那么当非000的数字个数>120>120>120时根据鸽巢原理直接判定答案为333
否则n≤120n \leq 120n≤120
直接建图,floydfloydfloyd求最小环
代码
#include <bits/stdc++.h>
#define linf (1ll<<60)
#define iinf 0x3f3f3f3f
#define rep(_i,_n) for(_i=1;_i<=(n);_i++)
using namespace std;
#define maxn 210
typedef long long ll;
ll d[maxn][maxn], m[maxn][maxn];
ll a[100010];
vector<ll> Lis[100];
int main()
{
ios::sync_with_stdio(false);
ll i, n, ans=linf, t, j, k, tot=0;
cin>>n;
for(i=1;i<=n;i++)
{
cin>>a[++tot];
if(a[tot]==0)tot--;
}
n=tot;
if(n>200)
{
cout<<3;
return 0;
}
for(i=1;i<=n;i++)for(j=1;j<=n;j++)d[i][j]=m[i][j]=iinf;
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++)
if(a[i]&a[j])d[i][j]=d[j][i]=m[i][j]=m[j][i]=1;
for(k=1;k<=n;k++)
{
for(i=1;i<k;i++)
for(j=i+1;j<k;j++)
if(d[i][j]+m[i][k]+m[k][j]<ans and d[i][j]+m[i][k]+m[k][j]>2)
ans=d[i][j]+m[i][k]+m[k][j];
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(d[i][k]+d[k][j]<d[i][j])
d[i][j]=d[i][k]+d[k][j];
}
if(ans<iinf)cout<<ans<<endl;
else cout<<-1<<endl;
return 0;
}