首页 > 试题广场 >

完美序列

[编程题]完美序列
  • 热度指数:790 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
我们定义一个完美序列为:这个序列的大于的元素个数超过不大于的元素
现在给你一个序列,想让你找到它的连续子序列中完美序列的最长长度是多少?
连续子序列的意思是序列中一段连续的序列,比如,序列1 2 3 里面连续的子序列有1 2或者2 3 但是1 3不是连续子序列

输入描述:
对于每一组测试数据,第一行输入两个整数代表这个序列的长度和要判断的元素
接下来输入个整数,代表系列中第个元素


输出描述:
对于每组测试数据,输出一个答案。
示例1

输入

7 8
9 9 6 0 6 6 9

输出

3

说明

满足要求的是\text [9,9,6] 
示例2

输入

5 8
9 9 6 0 9

输出

5

说明

满足要求的是\text [9 9 6 0 9] 
使用预处理技巧,构建一个辅助数组prevCount,prevCount[i]存储arr[0:i]中大于k的元素个数。然后穷举区间的两个端点,利用prevCount计算每个区间内大于k的元素个数,一旦大于k的元素个数超过不大于k的元素个数就更新最大的序列长度。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] params = br.readLine().split(" ");
        int n = Integer.parseInt(params[0]), k = Integer.parseInt(params[1]);
        String[] strArr = br.readLine().split(" ");
        int[] arr = new int[n];
        int[] prevCount = new int[n];
        for(int i = 0; i < n; i++){
            arr[i] = Integer.parseInt(strArr[i]);
            if(i == 0){
                prevCount[i] = arr[i] > k? 1: 0;
            }else{
                prevCount[i] = prevCount[i - 1] + (arr[i] > k? 1: 0);
            }
        }
        int maxLen = 0;
        for(int left = -1; left < n - 1; left++){
            for(int right = left + 1; right < n; right++){
                // 区间(left,right]中大于k的元素个数
                int gtkCnt = prevCount[right] - (left >= 0? prevCount[left]: 0);
                if(2*gtkCnt > right - left) {
                    maxLen = Math.max(maxLen, right - left);
                }
            }
        }
        System.out.println(maxLen);
    }
}

编辑于 2022-01-03 00:26:04 回复(0)

使用前缀和记录到当前的大于k比小于等于k的数量,找前面到当前的完美序列,只需满足后面的前缀和大于前面的前缀和,这样这段区间就是完美序列。从前往后遍历的一定符合到当前的最长,找的break就可以。时间复杂度为O(n^2)。

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
//#define mod 998244353
#define mod 1000000007
#define ll long long
using namespace std;
const int N=1e6+5;
const double eps=1e-8;
int n,m,k;
void solve(){
    cin>>n>>k;
    vector<int>vc(n+5,0);
    int sum=0;
    for(int i=0;i<n;i++){
        int x;cin>>x;
        if(x>k){
            sum++;
        }
        else{
            sum--;
        }
        vc[i+1]=sum;
    }
    int maxx=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=i;j++){
            if(vc[i]>vc[j-1]){
                maxx=max(maxx,i-j+1);
                break;
            }
        }
    }
    cout<<maxx<<'\n';
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cout<<fixed<<setprecision(10);
    //int t;
    //cin>>t;
    //while(t--){
        solve();
    //}
    return 0;
}
发表于 2022-01-12 16:14:16 回复(0)
#include<iostream>
using namespace std;
int a[10001] = {0};
int n,k;
int main() {
    cin>>n;
    cin>>k;
    for(int i=0; i<n; i++) {
        int temp;
        cin>>temp;
        a[i] = temp>k ? 1:-1;
    }
    for(int i=n-2; i>-1; i--) {
        a[i] += a[i+1];
    }
    int res = 0;
    for (int i=n-1; i>-1; i--) {
        if (i<res) {
            break;
        }
        for (int j=0; j<=i; j++) {
            if(i-j<res) {
                break;
            }
            if (a[j]-a[i+1]>0) {
                res = i-j+1>res ? (i-j+1) : res;
            }
        }
    }
    cout<<res <<endl;
    return 0;
}
发表于 2022-06-29 13:00:20 回复(1)
import java.util.*;

public class Main {
    // 完美序列-前缀和!
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt(), k = in.nextInt();
        int[] arr = new int[n];
        int[] pre = new int[n+1];
        for (int i = 0; i < n; i++) {
            int num = in.nextInt();
            arr[i] = num > k ? 1 : -1;
            pre[i+1] = pre[i] + arr[i];
        }
        int max = 0;
        for (int i = 1; i < n+1; i++) {
            for (int j = 0; j < i; j++) {
                if (pre[i]-pre[j] > 0) {
                    max = Math.max(max, i-j);
                }
            }
        }
        System.out.println(max);
    }
}
发表于 2022-07-13 22:39:26 回复(0)
#include<stdio.h>

#define M 100000

int main()
{
    int i,j,a[M],n,k;
    int x,y,max=-1000000,min=1000000;
    scanf("%d%d",&n,&k);
    for(i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    for(i=1;i<=n;i++)
    {
        x=0,y=0;
        for(j=i;j<=n;j++)
        {
            if(a[j]>k)
            {
                x++;
            }
            if(a[j]<k)
            {
                y++;
            }
            if(x>y)
            {
                if((j-i)>=(max-min))
                {
                    max=j;
                    min=i;

                }
            }
        }
    
    printf("%d",max-min+1);
}
发表于 2022-07-11 08:58:49 回复(0)
 #include <iostream>

using namespace std;

const int N = 10100;
int n, k;
int g[N];
int res = 0;
int main()
{
    cin >> n >> k;
    for(int i = 0; i < n; i ++) cin >> g[i];
    if(g[0] > k) g[0] = 1;
    else g[0] = -1;
    for(int i = 1; i < n; i ++)
    {
        if(g[i] > k ) g[i] = g[i - 1] + 1;
        else g[i] = g[i - 1] - 1;
    }
    for(int i = 0; i < n; i ++)
        if(g[i] > 0) res = i + 1;
    for(int i = 1; i + res < n; i ++)
    {
        for(int j = i + res; j < n; j ++)
            if(g[j] > g[i]) res = j - i;
    }
    cout << res;
}

理论应该是(n2),但是应该数据比较弱,优化了一下就过了

编辑于 2022-06-27 16:01:37 回复(0)

时间复杂度貌似最优就是 吗?python 提交的话记得选 jit 编译器 pypy ,要不然有一些测试样例会被卡时间。

n, k = list(map(int, input().split(" ")))
nums = list(map(int, input().split(" ")))
pre = [0]
for i in range(len(nums)):
    pre.append(pre[-1] + 1) if nums[i] > k else pre.append(pre[-1])

result = float("-inf")
for i in range(len(nums)):
    for j in range(i, len(nums)):
        gt_k = pre[j + 1] - pre[i]
        if gt_k > (j - i + 1 - gt_k):
            result = max(result, j - i + 1)
print(result)
编辑于 2022-03-14 22:39:38 回复(0)