计蒜客2019蓝桥杯国赛B组模拟赛 区间并(编程大题)

计蒜客2019蓝桥杯国赛B组模拟赛题解汇总:

https://blog.csdn.net/daixinliangwyx/article/details/90231587

 

第六题

标题:区间并


解法:只会暴力做法过30%。枚举所有答案区间,再枚举两个不相交的排列子区间看能不能交集成答案区间。稍微优化一下就是对于第二个子区间不用遍历右端点,因为已经有了答案区间的长度和第一个子区间的长度,是可以得到第二个子区间的长度的,并且有左端点,所以可以直接得到右端点。

30%代码:

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.*;


public class Main {
    public static InputReader in = new InputReader(new BufferedInputStream(System.in));
    public static PrintWriter out = new PrintWriter(System.out);
    public static int n;
    public static int[] a = new int[300010];
    public static long ans;
    public static TreeSet<Integer> ts;

    public static void main(String[] args) {
        n = in.nextInt();
        ans = 0;
        for (int i = 1; i <= n; i++) {
            a[i] = in.nextInt();
        }
        for (int l = 1; l < n; l++) {
            for (int r = l+1; r <= n; r++) {//数值区间[l, r]
                int flag = 0;
                for (int l1 = 1; l1 < n; l1++) {
                    for (int r1 = l1; r1 < n; r1++) {//排列中的第一个区间 a[l1, r1]
                        for (int l2 = r1+1; l2 <= n; l2++) { //第二个区间 a[l2, l2+r-l-r1+l1-1]
                            ts = new TreeSet<>();
                            for (int i = l1; i <= r1; i++)
                                ts.add(a[i]);
                            for (int i = l2; i <= l2+r-l-r1+l1-1; i++)
                                ts.add(a[i]);
                            if (ts.last() == r && ts.first() == l) {
                                ans++;
                                flag = 1;
                                break;
                            }
                        }
                        if (flag == 1) break;
                    }
                    if (flag == 1) break;
                }
            }
        }
        out.println(ans);
        out.flush();
        out.close();
    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public String nextLine() {
            String str = null;
            try {
                str = reader.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        public Double nextDouble() {
            return Double.parseDouble(next());
        }

        public BigInteger nextBigInteger() {
            return new BigInteger(next());
        }

    }
}

100%代码:

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int N = 1e6 + 7;
const int mod = 1e9 + 7;
int a[N+10];

int main(){
    int n,k,x;
    memset(a,0,sizeof(a));
    scanf("%d%d",&n,&k);
    for(int i=0;i<n;i++){
        scanf("%d",&x);
        a[x]++;//x的个数+1 
    }
    int ans = 1;
    //枚举gcd可能出现的值:从i=2 ~ N; 
    for(int i = 2 ;i < N; i++){
        int cnt = 0;
        for(int j = i;j < N; j += i) cnt += a[j]; //能被i整除的数 一定是 i i+i i+i+i .... 
        if(cnt >= k) ans = i;//比k大 那么选出k个数 他们的gcd就是当前的i 
    }
    printf("%d\n",ans);
    return 0;
} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值