zoukankan      html  css  js  c++  java
  • JZOJ 2197. 【中山市选2010】三核苷酸

    题目

       

    Description

         三核苷酸是组成DNA序列的基本片段。具体来说,核苷酸一共有4种,分别用’A’,’G’,’C’,’T’来表示。而三核苷酸就是由3个核苷酸排列而成的DNA片段。三核苷酸一共有64种,分别是’AAA’,’AAG’,…,’GGG’。给定一个长度为L的DNA序列,一共可以分辨出(L-2)个三核苷酸。现在我们想用一些统计学的方法来进行一些分析,步骤如下:
    1. 1.对于这(L-2)个三核苷酸,我们从左到右给予编号,分别为1到L-2。
      2.从这(L-2)个三核苷酸挑选一对出来,一共有(L-2)*(L-3)/2种可能。如果某一对三核苷酸是一样的,我们就记录他们之间的距离。他们之间的距离定义为他们的编号之差。
      3.根据我们所记录的“样本数据”,我们现在需要计算样本数据的方差。方差的计算公式是S2=[(x1-X) 2+(x2-X) 2+…+(xn-X)2]/n, X=(x1+x2+…+xn)/n。如果样本的大小n=0,那么我们认为S2=X=0。
     
    例如,我们要统计DNA序列’ATATATA’:
    1. 1. 为三核苷酸编号. L1: ATA, L2:TAT, L3:ATA, L4:TAT, L5:ATA.
      2.  (L1,L3)=2, (L1,L5)=4, (L3,L5)=2, (L2,L4)=2. 所以样本数据是2,4,2,2.
      3.  样本数据平均值X=(2+4+2+2)/4=2.5.
    方差S2=[(2-2.5)2+(4-2.5) 2+(2-2.5)2+(2-2.5)2]/4=0.75.
           给定一个DNA序列,请你计算出它的方差。
           
     

    Input

      输入包含多组测试数据。第一行包含一个正整数T,表示测试数据数目。每组数据包含一个由’A’,’G’,’C’,’T’组成的字符串,代表要统计的DNA序列。DNA序列的长度大于等于3且不会超过100000。

    Output

      对每组测试数据,输出一行答案,为一个保留6位精度的实数,代表S2的值。如果你的答案和标准答案的“相对误差”小于1e-8,你的答案会被视为正确的答案。
     

    Sample Input

    1
    ATATATA

    Sample Output

    0.750000
     

    Data Constraint

     
     

    Source / Author: 中山市选2010 tri

    分析

    •   

    代码

     1 #include<vector>
     2 #include<stdio.h>
     3 #include<string.h>
     4 #include<algorithm>
     5 using namespace std;
     6 vector<long long> c[64];
     7 int n,T,d[128]; char t[100010];
     8 long long s[100010],s2[100010],S,S2,N;
     9 void fun(){
    10     scanf("%s",t+1); 
    11     n=strlen(t+1); 
    12     S=S2=N=0;
    13     for(int i=3;i<=n;++i) 
    14        c[d[t[i]]+d[t[i-1]]*4+d[t[i-2]]*16].push_back(i);
    15     for(int i=0;i<64;++i) 
    16       if(c[i].size()>1){
    17         N+=c[i].size()*(c[i].size()-1)>>1;
    18         for(int j=0,z=c[i].size();j<z;++j)
    19             s[j+1]=s[j]+c[i][j],s2[j+1]=s2[j]+c[i][j]*c[i][j];
    20         for(int j=1,z=c[i].size();j<z;++j)
    21             S+=c[i][j]*j-s[j],S2+=c[i][j]*c[i][j]*j+s2[j]-2*c[i][j]*s[j];
    22     }
    23     if(N==0) puts("0.000000");
    24     else printf("%.6lf
    ",-(double)S/N*S/N+(double)S2/N);
    25 }
    26 int main(){
    27     freopen("tri.in","r",stdin);
    28     freopen("tri.out","w",stdout); 
    29     d['A']=0; d['G']=1; d['C']=2; d['T']=3;
    30     for(scanf("%d",&T);T--;fun())
    31         for(int i=0;i<64;++i) c[i].clear();
    32 }

     

     

     

     

    为何要逼自己长大,去闯不该闯的荒唐
  • 相关阅读:
    How To Build CyanogenMod Android for smartphone
    CentOS安装Code::Blocks
    How to Dual boot Multiple ROMs on Your Android SmartPhone (Upto Five Roms)?
    Audacious——Linux音乐播放器
    How to Dual Boot Multiple ROMs on Your Android Phone
    Everything You Need to Know About Rooting Your Android Phone
    How to Flash a ROM to Your Android Phone
    什么是NANDroid,如何加载NANDroid备份?
    Have you considered compiled a batman-adv.ko for android?
    BATMAN—Better Approach To Mobile Adhoc Networking (B.A.T.M.A.N.)
  • 原文地址:https://www.cnblogs.com/zjzjzj/p/10701607.html
Copyright © 2011-2022 走看看