UVA - 1481 Genome Evolution 公式+二分

题目大意:给出两条长度均为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 150010
char 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;
		else
			left = 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;
	else
		return false;	
}

int main() {
	while(scanf("%d%d",&n, &p) == 2 && n + p) {
		scanf("%s%s",str1,str2);
		if(solve())
			printf("%d\n",ans);
		else
			printf("No solution.\n");
	}
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值