【JZOJ100047】基因變異【BFS】
阿新 • • 發佈:2018-12-31
題目大意:
題目連結:https://jzoj.net/senior/#main/show/100047
題目圖片:
http://wx1.sinaimg.cn/mw690/0060lm7Tly1fy7gss4ijmj30j50cujrv.jpg
http://wx4.sinaimg.cn/mw690/0060lm7Tly1fy7gss4gyaj30j20asdfx.jpg
已知陣列
,兩種操作:
- 將 變成
- 將 二進位制下任意一位取反。
求從 變成 的最少步數。
思路:
如果我們有一個數
使得
,那麼很明顯的
就是我們要求的答案。
反過來得
。
所以,其實
到
的最少步數就是
到
的最少步數!
那麼就從
開始
,求出不超過
的答案(因為
最大就是
了)。然後就可以
輸出了。
思維好題。
程式碼:
#include <cstdio>
#include <queue>
#define ri register
using namespace std;
const int N=1200000;
int n,u,v,Q,a[N],s,t,ans[N];
bool vis[N];
char c;
int read()
{
u=0;
c=getchar();
while (c<'0'||c>'9') c=getchar();
while (c>='0'&&c<='9')
u=(u<<3)+(u<<1)+c-48,c=getchar();
return u;
}
int write(int x)
{
if (x>9) write(x/10);
putchar(x%10+48);
}
void bfs()
{
queue<int> q;
q.push(0);
vis[0]=1;
while (q.size())
{
u=q.front();
q.pop();
for (ri int i=1;i<=n;i++) //選擇每一個數xor
if (!vis[u^a[i]])
{
vis[u^a[i]]=1;
ans[u^a[i]]=ans[u]+1;
q.push(u^a[i]);
}
for (ri int i=0;i<=19;i++) //選擇每一位取反
{
if ((u&(1<<i))==(1<<i)) v=u-(1<<i);
else v=u+(1<<i);
if (!vis[v])
{
vis[v]=1;
ans[v]=ans[u]+1;
q.push(v);
}
}
}
}
int main()
{
n=read();
Q=read();
for (ri int i=1;i<=n;i++)
a[i]=read();
bfs();
while (Q--)
{
s=read();
t=read();
write(ans[s^t]);
putchar(10);
}
return 0;
}