【题目描述】:
21 世纪是生物学的世纪,以遗传与进化为代表的现代生物理论越来越多的进入了我们的视野。
如同大家所熟知的,基因是遗传因子,它记录了生命的基本构造和性能。因此生物进化与基因的变异息息相关,考察基因变异的途径对研究生物学有着至关重要的作用。现在,让我们来看这样一个模型:
1、所有的基因都可以看作一个整数或该整数对应的二进制码;
2、在 1 单位时间内,基因 x 可能会在其某一个二进制位上发生反转;
3、在 1 单位时间内,基因 x 可能会遭到可感染基因库内任一基因y的影响而突变为 x XOR y。
现在给出可感染基因库,Q 组询问,每组给出初始基因与终止基因,请你分别计算出每种变异最少要花费多少个单位时间。
【输入描述】:
第 1 行两个整数 N, Q;
第 2 行 N 个用空格隔开的整数分别表示可感染基因库内的基因;
接下来 Q 行每行两个整数 S、T,分别表示初始基因与终止基因。
【输出描述】:
输出 Q 行,依次表示每组初始基因到终止基因间最少所花时间。
【样例输入】:
3 3
1 2 3
3 4
1 2
3 9
【样例输出】:
2
1
2
【时间限制、数据范围及描述】:
时间:1s 空间:256M
对于 20%的数据,N=0;
额外 40%的数据,1≤Q≤100,所有基因表示为不超过 10^4 的非负整数;
对于 100%的数据,0≤N≤20,1≤Q≤10^5,所有基因表示为不超过 10^6 的非负整数。
思路
每个数字最多至多被使用一次
所以 设fi,j仅使用前i个量[具体见方程]到达j的最小步数
那么 f20,S^T即答案
代码
#include<cmath> #include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int n,qq,s,t,a[75]; int dis[1<<20],k,x; void bfs() { queue<int> q; memset(dis,-1,sizeof(dis)); q.push(0); dis[0]=0; while(!q.empty()) { k=q.front(); q.pop(); for(int i=1; i<=n+20; i++) { x=k^a[i]; if(dis[x]!=-1) continue; dis[x]=dis[k]+1; q.push(x); } } } int main () { scanf("%d%d",&n,&qq); for(int i=1; i<=n; i++) scanf("%d",&a[i]); a[n+1]=1; for(int i=n+2; i<=n+20; i++) a[i]=2*a[i-1]; bfs(); for(int i=1,s,t; i<=qq; i++) { scanf("%d%d",&s,&t); printf("%d\n",dis[s^t]); } return 0; }
原文地址:https://www.cnblogs.com/mysh/p/11524963.html
时间: 2024-10-11 07:33:58