JZOJ 100047. 【NOIP2017提高A组模拟7.14】基因变异
Description
21 世紀是生物學的世紀,以遺傳與進化為代表的現代生物理論越來越多的 進入了我們的視野。 如同大家所熟知的,基因是遺傳因子,它記錄了生命的基本構造和性能。 因此生物進化與基因的變異息息相關,考察基因變異的途徑對研究生物學有著 至關重要的作用。現在,讓我們來看這樣一個模型:
1、所有的基因都可以看作一個整數或該整數對應的二進制碼;
2、在 1 單位時間內,基因 x 可能會在其某一個二進制位上發生反轉;
3、在 1 單位時間內,基因 x 可能會遭到可感染基因庫內任一基因 y 的影響 而突變為 x XOR y。
現在給出可感染基因庫,Q 組詢問,每組給出初始基因與終止基因,請你 分別計算出每種變異最少要花費多少個單位時間。
Input
第 1 行兩個整數 N, Q; 第 2 行 N 個用空格隔開的整數分別表示可感染基因庫內的基因; 接下來 Q 行每行兩個整數 S、T,分別表示初始基因與終止基因。
Output
輸出 Q 行,依次表示每組初始基因到終止基因間最少所花時間。
Sample Input
3 3
1 2 3
3 4
1 2
3 9
Sample Output
2
1
2
Data Constraint
對于 20%的數據,N = 0;
對于額外 40%的數據,1 ≤ Q ≤ 100,所有基因表示為不超過 10^4 的非負整 數;
對于 100%的數據,0 ≤ N ≤ 20,1 ≤ Q ≤ 10^5,所有基因表示為不超過 10^6 的 非負整數。
Solution
題目給出若干個詢問 x,y ,問 x 變成 y 的最小變換次數。
變換有兩種:與給定的數異或 和 將自身某個二進制位取反 。
可以發現,后者相當于與 2 的冪數 (二進制為 1后面全0)異或。
又可以發現,令 z=x?xor?y ,則 z 的二進制中 1 的個數即為 x 與 y 之間的“差異”。
所以從 0 轉化成 z 的最小變換次數是等價于所求的答案的。
由于初始狀態只是 0<script type="math/tex" id="MathJax-Element-990">0</script> (單源),我們就以其為起點做一次 BFS (不斷異或),
預處理出轉移到任意值的最小步數,讀入時直接輸出即可。
Code
#include<cstdio> #include<cstring> using namespace std; const int N=2e6+1; int f[41],dis[N],que[N]; bool bz[N]; inline int read() {int X=0,w=1; char ch=0;while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();return X*w; } int main() {int n=read(),q=read();for(int i=1;i<=n;i++) f[i]=read();for(int i=0;i<20;i++) f[++n]=1<<i;int l=que[1]=dis[0]=0,r=bz[0]=1;while(l<r){int x=que[++l];for(int i=1;i<=n;i++){int y=x^f[i];if(!bz[y]){dis[y]=dis[x]+1;bz[que[++r]=y]=true;}}}while(q--) printf("%d\n",dis[read()^read()]);return 0; }總結
以上是生活随笔為你收集整理的JZOJ 100047. 【NOIP2017提高A组模拟7.14】基因变异的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JZOJ 100046. 【NOIP20
- 下一篇: BZOJ 2038: [2009国家集训