首先上题目:

A DNA sequence can be represented as a string consisting of the letters A, C, G and T, which correspond to the types of successive nucleotides in the sequence. Each nucleotide has an impact factor, which is an integer. Nucleotides of types A, C, G and T have impact factors of 1, 2, 3 and 4, respectively. You are going to answer several queries of the form: What is the minimal impact factor of nucleotides contained in a particular part of the given DNA sequence?

The DNA sequence is given as a non-empty string S =S[0]S[1]...S[N-1] consisting of N characters. There are M queries, which are given in non-empty arrays P and Q, each consisting of M integers. The K-th query (0 ≤ K < M) requires you to find the minimal impact factor of nucleotides contained in the DNA sequence between positions P[K] and Q[K] (inclusive).

For example, consider string S = CAGCCTA and arrays P, Q such that:

    P[0] = 2    Q[0] = 4
P[1] = 5 Q[1] = 5
P[2] = 0 Q[2] = 6

The answers to these M = 3 queries are as follows:

  • The part of the DNA between positions 2 and 4 contains nucleotides G and C (twice), whose impact factors are 3 and 2 respectively, so the answer is 2.
  • The part between positions 5 and 5 contains a single nucleotide T, whose impact factor is 4, so the answer is 4.
  • The part between positions 0 and 6 (the whole string) contains all nucleotides, in particular nucleotide Awhose impact factor is 1, so the answer is 1.

Assume that the following declarations are given:

struct Results {
  int * A;
  int M;
};

Write a function:

struct Results solution(char *S, int P[], int Q[], int M);

that, given a non-empty zero-indexed string S consisting of N characters and two non-empty zero-indexed arrays P and Q consisting of M integers, returns an array consisting of M integers specifying the consecutive answers to all queries.

The sequence should be returned as:

  • a Results structure (in C), or
  • a vector of integers (in C++), or
  • a Results record (in Pascal), or
  • an array of integers (in any other programming language).

For example, given the string S = CAGCCTA and arrays P, Q such that:

    P[0] = 2    Q[0] = 4
P[1] = 5 Q[1] = 5
P[2] = 0 Q[2] = 6

the function should return the values [2, 4, 1], as explained above.

Assume that:

  • N is an integer within the range [1..100,000];
  • M is an integer within the range [1..50,000];
  • each element of arrays P, Q is an integer within the range [0..N − 1];
  • P[K] ≤ Q[K], where 0 ≤ K < M;
  • string S consists only of upper-case English letters A, C, G, T.

Complexity:

  • expected worst-case time complexity is O(N+M);
  • expected worst-case space complexity is O(N), beyond input storage (not counting the storage required for input arguments).

Elements of input arrays can be modified.

Copyright 2009–2015 by Codility Limited. All Rights Reserved. Unauthorized copying, publication or disclosure prohibited.

2.题目分析

这个题目看上去蛮简单,就是在一个序列中的任意一段slice中,找出出现过的最小值。

不过要求时间复杂度为O(N),便费了一些周折。

1. 首先是将str转换为int 数组,为后面的处理加速,免去每次都要遍历。

先用strlen函数获得str的长度,再通过temp 指针遍历这个str,将A转为1,C转为2,G转为3,T转为4。

获得了这个数组之后就比较好操作了~

2. 获得任何段的最小值看似很简单,遍历就可以了,不过这样时间复杂度就会变为O(N*M)。

如何减少时间复杂度呢?答案是用空间换时间。

通过prefix的想法,我先统计出了在每一个位置之前包括这个位置,1所出现的次数,2所出现的次数,3所出现的次数,4所出现的次数。

分别存入数组A,B,C,D;

每次查询时,只要判断A[end of slice]-A[Begin of Slice]是否大于零,即可判断是否1出现过。这一步的时间复杂度就从O(N)降为了O(1);

注意,需要检查str[begin of slice]是否为1,因为当这个位置是1时,是不会表现出来的。

其余查询依然,通过增加空间复杂度,降低了时间的复杂度。

找出最小的出现值即可。

3.代码如下:

 // you can write to stdout for debugging purposes, e.g.
// printf("this is a debug message\n"); struct Results solution(char *S, int P[], int Q[], int M) {
struct Results result;
// write your code in C99
int len = strlen(S);
// printf("len is %d",len); int arr[len];
int i;
char* temp = S;
for(i=;i<len;i++)
{
if(*temp=='C')
{
arr[i]=;
}
else if(*temp=='A')
{
arr[i]=;
}
else if(*temp=='G')
{
arr[i]=;
}
else if(*temp=='T')
{
arr[i]=;
}
temp++;
} int A[len];
int B[len];
int C[len];
int D[len]; if(arr[]==)
{
A[]=;
B[]=;
C[]=;
D[]=;
} if(arr[]==)
{
A[]=;
B[]=;
C[]=;
D[]=;
} if(arr[]==)
{
A[]=;
B[]=;
C[]=;
D[]=;
} if(arr[]==)
{
A[]=;
B[]=;
C[]=;
D[]=;
} // printf("%d %d %d %d \n",A[0],B[0],C[0],D[0]);
for(i=;i<len;i++)
{
// printf("%d\n",arr[i]);
if(arr[i]==)
{
A[i]=A[i-]+;
B[i]=B[i-];
C[i]=C[i-];
D[i]=D[i-];
} if(arr[i]==)
{
A[i]=A[i-];
B[i]=B[i-]+;
C[i]=C[i-];
D[i]=D[i-];
} if(arr[i]==)
{
A[i]=A[i-];
B[i]=B[i-];
C[i]=C[i-]+;
D[i]=D[i-];
} if(arr[i]==)
{
A[i]=A[i-];
B[i]=B[i-];
C[i]=C[i-];
D[i]=D[i-]+;
} // printf("%d %d %d %d \n",A[i],B[i],C[i],D[i]);
}
result.A = malloc(sizeof(int)*M);
result.M = M; for(i=;i<M;i++)
{
int tempP = P[i];
int tempQ = Q[i];
if(arr[tempP]== || (A[tempQ]-A[tempP]) > )
{
result.A[i]=;
}
else if(arr[tempP]== || (B[tempQ]-B[tempP]) > )
{
result.A[i]=;
}
else if(arr[tempP]== || (C[tempQ]-C[tempP]) > )
{
result.A[i]=;
}
else
{
result.A[i]=;
}
} return result;
}

GenomicRangeQuery /codility/ preFix sums的更多相关文章

  1. 【题解】【数组】【Prefix Sums】【Codility】Genomic Range Query

    A non-empty zero-indexed string S is given. String S consists of N characters from the set of upper- ...

  2. 【题解】【数组】【Prefix Sums】【Codility】Passing Cars

    A non-empty zero-indexed array A consisting of N integers is given. The consecutive elements of arra ...

  3. Codeforces 837F Prefix Sums

    Prefix Sums 在 n >= 4时候直接暴力. n <= 4的时候二分加矩阵快速幂去check #include<bits/stdc++.h> #define LL l ...

  4. CodeForces 837F - Prefix Sums | Educational Codeforces Round 26

    按tutorial打的我血崩,死活挂第四组- - 思路来自FXXL /* CodeForces 837F - Prefix Sums [ 二分,组合数 ] | Educational Codeforc ...

  5. Educational Codeforces Round 26 [ D. Round Subset ] [ E. Vasya's Function ] [ F. Prefix Sums ]

    PROBLEM D - Round Subset 题 OvO http://codeforces.com/contest/837/problem/D 837D 解 DP, dp[i][j]代表已经选择 ...

  6. CodeForces 1204E"Natasha, Sasha and the Prefix Sums"(动态规划 or 组合数学--卡特兰数的应用)

    传送门 •参考资料 [1]:CF1204E Natasha, Sasha and the Prefix Sums(动态规划+组合数) •题意 由 n 个 1 和 m 个 -1 组成的 $C_{n+m} ...

  7. CF1303G Sum of Prefix Sums

    点分治+李超树 因为题目要求的是树上所有路径,所以用点分治维护 因为在点分治的过程中相当于将树上经过当前$root$的一条路径分成了两段 那么先考虑如何计算两个数组合并后的答案 记数组$a$,$b$, ...

  8. codeforces:Prefix Sums分析和实现

    题目大意: 给出一个函数P,P接受一个数组A作为参数,并返回一个新的数组B,且B.length = A.length + 1,B[i] = SUM(A[0], ..., A[i]).有一个无穷数组序列 ...

  9. [CF1204E]Natasha,Sasha and the Prefix Sums 题解

    前言 本文中的排列指由n个1, m个-1构成的序列中的一种. 题目这么长不吐槽了,但是这确实是一道好题. 题解 DP题话不多说,直接状态/变量/转移. 状态 我们定义f表示"最大prefix ...

随机推荐

  1. 电脑控制Android设备的软件——Total Control

    最早开始搞Android开发时,为了调试方便,想找一个Android下的远程控制软件,支持在电脑端远程控制和同步显示Android设备.先后试了360手机助手.Mobizen.Vysor和Mirror ...

  2. Spring MVC 使用HiddenHttpMethodFilter配置Rest风格的URL

    /** Rest 风格的 URL. 以 CRUD 为例: 新增: /order POST 修改: /order/1 PUT update?id=1 获取:/order/1 GET get?id=1 删 ...

  3. NYOJ 187

    快速查找素数 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 现在给你一个正整数N,要你快速的找出在2.....N这些数里面所有的素数. 输入 给出一个正整数数N(N&l ...

  4. iOS 3D Touch实践

    本文主要讲解3DTouch各种场景下的开发方法,开发主屏幕应用icon上的快捷选项标签(Home Screen Quick Actions),静态设置 UIApplicationShortcutIte ...

  5. C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本 - 外部服务调用、内部服务调用优化,面向服务化的

    现在的信息系统越来越复杂,越来越庞大,不仅需要内部是一个整体,而且还需要提供很多对外的服务调用. 1:别人如何调用最方便?用不同的开发语言调用.例如app.手持设备.服务器.2:服务的返回状态是什么样 ...

  6. Java中的instanceof关键字

    instanceof是Java的一个二元操作符,和==,>,<是同一类东东.由于它是由字母组成的,所以也是Java的保留关键字.它的作用是测试它左边的对象是否是它右边的类的实例,返回boo ...

  7. MySQL 常用的sql语句小结(待续)

    mysql 常用的sql语句 1.查看数据库各个表中的记录数 USE information_schema; SELECT table_name,table_rows FROM tables WHER ...

  8. Asp.Net MVC及Web API框架配置会碰到的几个问题及解决方案(转)

      前言 刚开始创建MVC与Web API的混合项目时,碰到好多问题,今天拿出来跟大家一起分享下.有朋友私信我问项目的分层及文件夹结构在我的第一篇博客中没说清楚,那么接下来我就准备从这些文件怎么分文件 ...

  9. 微信快速开发框架(七)--发送客服信息,版本更新至V2.2 代码已更新至github

    在V2版本发布的博文中,已经介绍了大多数Api的用法,同时也收到了很多意见,其中发布了几个修正版本,修改了几个bug,在此感谢大家的使用,有了大家的支持,相信快速开发框架会越来越好,也会越来越完善的. ...

  10. python基础-修改haproxy配置文件

    需要掌握的知识: 1.函数 2.文件处理 3.tag的用法 4.程序的解耦 需求: 1:查询 2:添加 3:删除 4:修改 5:退出 haproxy.conf 配置文件内容: global log 1 ...