LA3716 (单调队列)

题目大意:
有两个长度是n的序列,找出一个[l,r]的区间,这个区间内有不超过%p的数满足A[i] != B[i],问区间长度最长是多少。

思路:
计算出从开头到当前位置i有多少个不同的字母。
(i - j) * p >= (sum[i] - sum[j]) * 100
所以 sum[j]* 100 - j * p >= sum[i] * 100 - i *p因此我们要从大到小的顺序进行排序才可以满足题目的要求

代码:

#include <iostream>
using namespace std;
#include <stdio.h>
#include <algorithm>

const int N = 150005;
struct node {
    int fa,len;
}c[N];
char a[N],b[N];

bool cmp(node x,node y) {
    if(x.fa != y.fa)
        return x.fa > y.fa;
    return x.len < y.len;
}

int n,p;

int main() {
    while(scanf("%d %d",&n,&p) && n) {
        scanf("%s,%s",a + 1, b + 1);
        int cnt = 0; 
        int res = 0;
        c[0].fa = c[0].len = 0;
        for(int i = 1; i <= n; i++) {
            if(a[i] != b[i])
                cnt++;
            c[i].fa = cnt * 100 - i *p;
            c[i].len = i;
        }
        sort(c,c + n + 1,cmp);
        for(int i = 1, j = c[0].len; i <= n; i++)
            if(j < c[i].len)
                res = max(res,c[i].len - j);
            else
                j = c[i].len;//如果j大于c[i].len就要更新j的长度进行比较 类似与求最大的串的和。。
        if(res > 0)
            printf("%d\n",res);
        else
            printf("NO solution.\n");
    }
    return 0;
}

你可能感兴趣的:(LA3716 (单调队列))