UVA 1481 Genome Evolution

Xi, a developmental biologist is working on developmental distances of chromosomes. A chromosome,
in the Xi’s simplistic view, is a permutation from n genes numbered 1 to n. Xi is working on an
evolutionary distance metric between two chromosomes. In Xi’s theory of evolution any subset of genes
lying together in both chromosomes is a positive witness for chromosomes to be similar.
A positive witness is a pair of sequence of the same length A and A ′ , where A is a consecutive
subsequence of the first chromosome, A ′ is a consecutive subsequence of the second chromosome, and A
is a permutation of A ′ . The goal is to count the number of positive witnesses of two given chromosomes
that have a length greater than one.

题目大意:给出A,B两个序列,设a为A的一个连续子序列,b为B的一个连续子序列,求a,b中元素相同的(a,b)对数 如{1,3,2}和{3,1,2}相等

解题报告:应该写的是正解吧,毕竟这么简短,首先我们把B数组的\(b_i\)替换成\(b_i\)在A数组中的位置,那么显然对于新的B数组,如果一个连续的子序列中正好对应某个区间内的连续一段,那么就符合条件,如{2,4,3}就符合条件,因为对于[2,4]这个连续区间,所以就是怎么求这样的子序列,本人开始想树状数组维护每个数出现的次数,仿佛还需要卡常,上波厕所突然想到如果区间长度L等于该区间数最大值和最小值差即可满足条件,厕所果然是思维圣殿,然后\(O(n^2)\)扫一边顺便记录最大最小值即可

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int N=3005;
int p[N],a[N],b[N],n;
void work()
{
	for(int i=1;i<=n;i++)scanf("%d",&b[i]),p[b[i]]=i;
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		a[i]=p[a[i]];
	}
	int ans=0,l,r;
	for(int i=1;i<=n;i++){
		l=r=a[i];
		for(int j=i+1;j<=n;j++){
			l=Min(l,a[j]);r=Max(r,a[j]);
			if(r-l==j-i)ans++;
		}
	}
	printf("%d\n",ans);
}

int main()
{
	while(~scanf("%d",&n) && n)work();
	return 0;
}

posted @ 2017-09-08 20:56  PIPIBoss  阅读(199)  评论(0编辑  收藏  举报