1. 程式人生 > >2018.12.15【NOIP提高組】模擬B組 JZOJ 100047 基因變異

2018.12.15【NOIP提高組】模擬B組 JZOJ 100047 基因變異

題目

JZOJ 100047 基因變異


思路

x   x o r   k = y

x\ xor\ k=y
x   x o r   y
= k x\ xor\ y=k

x   x o r
  y = 0   x o r   k x\ xor\ y=0\ xor\ k

也就是說,我們只需要得出0轉移到 x   x o r   y x\ xor\ y 的步數即可
用寬搜
時間複雜度: O ( m a x { x , y } + Q ) O(max\{x,y\}+Q)


程式碼

#pragma GCC optimize(2)
#include<queue>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
using namespace std;int n,a[41],m,x,y,cs,bs[1<<22];
inline int ask1(register int x)
{
	int ans=0;
	for(;x;x-=x&-x)ans++;
	return ans;
}
inline char Getchar()
{
    static char buf[100000],*p1=buf+100000,*pend=buf+100000;
    if(p1==pend)
	{
        p1=buf; pend=buf+fread(buf,1,100000,stdin);
        if (pend==p1) return -1;
    }
    return *p1++;
}
inline long long read()
{
	char c;int d=1;long long f=0;
	while(c=Getchar(),!isdigit(c))if(c==45)d=-1;f=(f<<3)+(f<<1)+c-48;
	while(c=Getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
	return d*f;
}
inline void write(register long long x)
{
	if(x<0)write(45),x=-x;
	if(x>9)write(x/10);
	putchar(x%10+48);
	return;
}
inline void bfs()//bfs預處理
{
	queue<int>q;int y;
	q.push(0);bs[0]=0;
	while(q.size())
	{
		int x=q.front();q.pop();
		for(register int i=1;i<=n;i++)//xor a[i]
		{
			y=x^a[i];
			if(!bs[y])
			{
				bs[y]=bs[x]+1;
				q.push(y);
			}
		}
		for(register int i=0;i<=20;i++)//單位取反
		{
			y=x^(1<<i);
			if(!bs[y])
			{
				bs[y]=bs[x]+1;
				q.push(y);
			}
		}
	}
}
signed main()
{
	n=read();m=read();
	for(register int i=1;i<=n;i++) a[i]=read();
	bfs();
	while(m--)
	{
		x=read();y=read();
		write(bs[x^y]);putchar(10);//輸出 
	}
}