基因变异

本秂侑毒 提交于 2019-11-29 16:07:47

【题目描述】:

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 的非负整数。

 

 

BFS。。。。。。

 

控诉季某。。。。。

 

考试时:

  我:季X?这道题BFS能过啊?

  季X:不可能的,稳得超时。

  我:不对吧,我觉得能过。

  季X:BFS复杂度与DFS差不多,有可能比DFS还高。

  我:哦。

 

然后,我就打了一个DFS。。。。。。。

 

mmp

 

 

 

#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define ll long long
const int N=25;
const int M=1<<20;
using namespace std;
int s[M*10];
int c[N];
int num[25]={1,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576};
int kdl[M];
bool vis[M];

inline int read(){
    int s=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-'){
            w=-1;
        }
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=s*10+ch-'0';
        ch=getchar();
    }
    return s*w;
}

int main(){
    int n,q;
    n=read();
    q=read();
    for(int i=1;i<=n;i++){
        c[i]=read();
    }
    memset(kdl,0x3f,sizeof(kdl));
    kdl[0]=0;
    int l=1,r=0;
    s[++r]=0;
    vis[0]=1;
    while(l<=r){
        int tmp=s[l];
        l++;
        vis[tmp]=0;
        for(int i=1;i<=21;i++){
            int hh=tmp^num[i];
            if(hh>=M||hh<0){
                continue;
            }
            if(kdl[tmp]+1<kdl[hh]&&vis[hh]==0){
                vis[hh]=1;
                kdl[hh]=kdl[tmp]+1;
                s[++r]=hh;
            }
        }
        for(int i=1;i<=n;i++){
            int hh=tmp^c[i];
            if(hh>=M||hh<0){
                continue;
            }
            if(kdl[tmp]+1<kdl[hh]&&vis[hh]==0){
                vis[hh]=1;
                kdl[hh]=kdl[tmp]+1;
                s[++r]=hh;
            }
        }
    }
    for(int i=1;i<=q;i++){
        int a,b;
        a=read();
        b=read();
        printf("%d\n",kdl[a^b]);
    }
    return 0;
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!