UVA - 1481 Genome Evolution 公式+二分

来源:互联网 发布:python私有变量 编辑:程序博客网 时间:2024/05/21 11:17

题目大意:给出两条长度均为n的DNA链A和B,你的任务是找出一段最长的区域,使得该区域内的突变位置不超过p%

解题思路:设sum1为两条DNA链前i个不同基因的数量,sum2为两条DNA链前j个不同基因的数量(j > i),因为要满足公式(sum2-sum1) / (j-i) >= p / 100,由公式变形的 sum2 * 100 - p * j >= sum1 * 100 - p * i。再设和sum2*100-p*j相似的式子的计算结果为value,设置一个数组存放alue

1.如果当前的value < 前一个value,则将这个value放入数组

2.如果当前的value >= 前一个value,就找到一个在数组最左边且小于等于当前value的value值,这两个value的距离差就是结果

#include<cstdio>#include<algorithm>using namespace std;#define maxn 150010char str1[maxn], str2[maxn];int n, p, ans, cnt;struct Point{int id, sum, value;}po[maxn], que[maxn];int find(int num) {int left = 0, right = cnt;while(left < right) {int mid = (left + right) / 2;if(que[mid].value <= num)right = mid;elseleft = mid + 1;}return que[left].id;}bool solve() {ans = 0;po[0].id = 0; po[0].sum = 0;po[0].value = 0;que[0] = po[0];cnt = 0;for(int i = 1; i <= n; i++) {po[i].id = i; po[i].sum = po[i-1].sum + (str1[i-1] != str2[i-1]);po[i].value = p * i - po[i].sum * 100;if(po[i].value < que[cnt].value)que[++cnt] = po[i];else {int id = find(po[i].value);ans = max(ans,po[i].id - id);}}if(ans)return true;elsereturn false;}int main() {while(scanf("%d%d",&n, &p) == 2 && n + p) {scanf("%s%s",str1,str2);if(solve())printf("%d\n",ans);elseprintf("No solution.\n");}return 0;}


0 0