UVa 1481 Genome Evolution 解题报告(枚举)

56 篇文章 0 订阅

1481 - Genome Evolution

Time limit: 3.000 seconds

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.

Input 

There are several test case in the input. Each test case starts with a line containing the number of genes (2$ \le$n$ \le$3000). The next two lines contain the two chromosomes, each as a list of positive integers. The input terminates with a line containing ``0'' which should not be processed as a test case.

Output 

For each test case, output a single line containing the number of positive witness for two chromosomes to be similar.

Sample Input 

4 
3 2 1 4 
1 2 4 3 
5 
3 2 1 5 4
3 2 1 5 4
0

Sample Output 

3 
10

    题意: 两个1-n的排列,问元素相同的长度大于等于2的连续子序列有多少对。

    做法其实很简单,别想太复杂。首先记录排列b中1-n各个数字出现的位置。在排列a中枚举起点,找出相应的在b中的位置。随着排列a元素的增加,更新对应的排列b中的最小位置和最大位置。如果二者长度相等,说明两个子排列元素相等。代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <string>
using namespace std;

#define ff(i, n) for(int i=0;i<(n);i++)
#define fff(i, n, m) for(int i=(n);i<=(m);i++)
#define dff(i, n, m) for(int i=(n);i>=(m);i--)
typedef long long LL;
typedef unsigned long long ULL;
void work();

int main()
{
#ifdef ACM
    freopen("in.txt", "r", stdin);
//    freopen("in.txt", "w", stdout);
#endif // ACM

    work();
}

/*****************************************/

int a[3333], b[3333];
int pos[3333];

void work()
{
    int n;
    while(~scanf("%d", &n) && n)
    {
        fff(i, 1, n) scanf("%d", a+i);
        fff(i, 1, n) scanf("%d", b+i), pos[b[i]] = i;

        int ans = 0;
        fff(i, 1, n)
        {
            int minP = pos[a[i]];
            int maxP = pos[a[i]];

            fff(j, i+1, n)
            {
                int p = pos[a[j]];
                minP = min(minP, p);
                maxP = max(maxP, p);

                if(maxP - minP == j - i)
                    ans++;
            }
        }

        printf("%d\n", ans);
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值