2018蓝桥杯C/C++真题题解(二)

简介: 2018蓝桥杯C/C++真题题解

E:快速排序


题目描述

本题为代码补全填空题,请将题目中给出的源代码补全,并复制到右侧代码框中,选择对应的编译语言(C/Java)后进行提交。若题目中给出的源代码语言不唯一,则只需选择其一进行补全提交即可。复制后需将源代码中填空部分的下划线删掉,填上你的答案。提交后若未能通过,除考虑填空部分出错外,还需注意是否因在复制后有改动非填空部分产生错误。


以下代码可以从数组 a[ ] 中找出第 k小的元素。


它使用了类似快速排序中的分治算法,期望时间复杂度是O(N)的。


请仔细阅读分析源码,填写划线部分缺失的内容。


源代码

C

#include <stdio.h>
int quick_select(int a[], int l, int r, int k) {
    int p = rand() % (r - l + 1) + l;
    int x = a[p];
    {int t = a[p]; a[p] = a[r]; a[r] = t;}
    int i = l, j = r;
    while(i < j) {
        while(i < j && a[i] < x) i++;
        if(i < j) {
            a[j] = a[i];
            j--;
        }
        while(i < j && a[j] > x) j--;
        if(i < j) {
            a[i] = a[j];
            i++;
        }
    }
    a[i] = x;
    p = i;
    if(i - l + 1 == k) return a[i];
    if(i - l + 1 < k) return quick_select( _____________________________ ); //填空
    else return quick_select(a, l, i - 1, k);
}
int main()
{
    int a[100];
    int n;
    scanf("%d %d",&n);
    for(int i=0;i<n;i++)
    scanf("%d",&a[i]);
    printf("%d\n", quick_select(a, 0, n-1, 5));
    return 0;
}

java

import java.util.Scanner;
import java.util.Random;
public class Main{
    public static int quickSelect(int a[], int l, int r, int k) {
        Random rand = new Random();
        int p = rand.nextInt(r - l + 1) + l;
        int x = a[p];
        int tmp = a[p]; a[p] = a[r]; a[r] = tmp;
        int i = l, j = r;
        while(i < j) {
                    while(i < j && a[i] < x) i++;
                    if(i < j) {
                            a[j] = a[i];
                            j--;
                    }
                    while(i < j && a[j] > x) j--;
                    if(i < j) {
                            a[i] = a[j];
                            i++;
                    }
            }
            a[i] = x;
            p = i;
            if(i - l + 1 == k) return a[i];
            if(i - l + 1 < k) return quickSelect( _________________________________ ); //填空
            else return quickSelect(a, l, i - 1, k);    
    }
    public static void main(String args[]) {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        int a[]=new int[110];
        for(int i=0;i<n;i++)
        {
          a[i]=scan.nextInt();
        }
        System.out.println(quickSelect(a, 0, n-1, 5));
    }
}

运行限制

最大运行时间:1s

最大运行内存: 256M

我是用的c,首先添加头文件#include  <stdlib.h>,随机函数rand()用。


首先快速排序要找一个基点,题目中是随机的,然后放到最后一位。左指针向右移动直到找到一个大于基数的数,将其复制到最后,随后右指针向左移动,直到找到一个小于基数的数,将其赋予左指针,以此循环,最后左右指针碰头,将基点赋予该位置。这样导致基点右边都是大于基点,左边都是小于基点。然后判断基点下标(以未移动的左指针开始算)适合符合。

#include <stdio.h>
#include <stdlib.h>
int quick_select(int a[], int l, int r, int k) {
    int p = rand() % (r - l + 1) + l;
    int x = a[p];
    {int t = a[p]; a[p] = a[r]; a[r] = t;}
    int i = l, j = r;
    while(i < j) {
        while(i < j && a[i] < x) i++;
        if(i < j) {
            a[j] = a[i];
            j--;
        }
        while(i < j && a[j] > x) j--;
        if(i < j) {
            a[i] = a[j];
            i++;
        }
    }
    a[i] = x;
    p = i;
    if(i - l + 1 == k) return a[i];
    if(i - l + 1 < k) return quick_select(a,i+1,r,k-i+l-1); 
//因为已经有i-l+1个小于的数了。
    else return quick_select(a, l, i - 1, k);
}
int main()
{
    int a[100];   
    int n;
    scanf("%d %d",&n);
    for(int i=0;i<n;i++)     //输入n个数
    scanf("%d",&a[i]);
    printf("%d\n", quick_select(a, 0, n-1, 5));
    return 0;
}


F:递增三元组


题目描述

给定三个整数数组


A = A1,A2,⋯AN],


B=[B1,B2,⋯BN],


C=[C1,C2,⋯CN],


请你统计有多少个三元组 (i,j,k) 满足:


N1≤i,j,k≤N;


Ai<Bj<Ck。


输入描述

第一行包含一个整数 N。


第二行包含 N 个整数 A1,A2,⋯AN。


第三行包含 N 个整数 B1,B2,⋯BN。


第四行包含 N 个整数 C1,C2,⋯CN。


其中1≤N≤105,0≤Ai,Bi,Ci≤105。


输出描述

输出一个整数表示答案。


输入输出样例

示例


输入

3
1 1 1
2 2 2
3 3 3

输出

27

运行限制

最大运行时间:2s

最大运行内存: 256M

#include <iostream>
#include <algorithm>
using namespace std;
int n;
int a[100005];
int b[100005];
int c[100005];
long long ans;
int main(){
  cin>>n;
  for(int i=0;i<n;i++){
    cin>>a[i];
  }
  for(int i=0;i<n;i++){
    cin>>b[i];
  }
  for(int i=0;i<n;i++){
    cin>>c[i];
  }
  sort(a,a+n);
  sort(b,b+n);
  sort(c,c+n);
  int m=0;
  int mm=0;
  int j = 0;
  int k = 0;
    //以b为中间值 在a数组 c数组中查找 
  for(int i=0;i<n;i++){
    while(j<n && a[j] < b[i]) j++; 
    while(k<n && c[k] <= b[i]) k++; 
    ans += (long long)(j) * (n-k); 
  }
    cout<<ans<<endl;
  return 0;
}

G:螺旋折线


题目描述

如下图所示的螺旋折线经过平面上所有整点恰好一次。

对于整点 (X,Y),我们定义它到原点的距离dis(X,Y) 是从原点到 (X,Y)的螺旋折线段的长度。


例如 dis(−2,−1)=9。


给出整点坐标 (X,Y),你能计算出 dis(X,Y) 吗?


输入描述

输入格式:


输入一行,X 和 Y ,−109≤X,Y≤109。


输出描述

输出 dis(X,Y)。


输入输出样例

示例


输入

0 1

输出

3

运行限制

最大运行时间:1s

最大运行内存: 256M

曼哈顿距离方法比较简单,一开始我是每个象限推导,好麻烦的。然后看到网上有曼哈顿距离。

http://t.csdn.cn/H0HpU

#include <iostream>
#include <cmath>
using namespace std;
long long x,y;
long long ans;
int main(){
  cin>>x>>y; 
  long long t=max(abs(x),abs(y));
  if(x>=y){
    ans=4*t*t+abs(x-t)+abs(y-t);
  }else{
    ans=4*t*t-abs(x-t)-abs(y-t);
  }
  cout<<ans;
  return 0;
}
相关文章
|
1月前
|
算法 测试技术 C++
【动态规划算法】蓝桥杯填充问题(C/C++)
【动态规划算法】蓝桥杯填充问题(C/C++)
|
1月前
|
人工智能 算法 BI
第十四届蓝桥杯省赛大学C组(C/C++)三国游戏
第十四届蓝桥杯省赛大学C组(C/C++)三国游戏
|
1月前
|
人工智能 C++
第十四届蓝桥杯省赛大学B组(C/C++)整数删除
第十四届蓝桥杯省赛大学B组(C/C++)整数删除
|
28天前
|
机器学习/深度学习 算法 关系型数据库
第十五届蓝桥杯C++B组省赛
第十五届蓝桥杯C++B组省赛
59 14
|
24天前
|
算法 C++
2022年第十三届蓝桥杯大赛C/C++语言B组省赛题解
2022年第十三届蓝桥杯大赛C/C++语言B组省赛题解
22 5
|
6月前
|
算法 测试技术 C++
小唐开始刷蓝桥(八)2013年第四届C/C++ B组蓝桥杯省赛真题
小唐开始刷蓝桥(八)2013年第四届C/C++ B组蓝桥杯省赛真题
|
6月前
|
算法 C++ 数据格式
小唐开始刷蓝桥(七)2014年第五届C/C++ B组蓝桥杯省赛真题
小唐开始刷蓝桥(七)2014年第五届C/C++ B组蓝桥杯省赛真题
|
6月前
|
算法 C++
小唐开始刷蓝桥(五)2016年第七届C/C++ B组蓝桥杯省赛真题
小唐开始刷蓝桥(五)2016年第七届C/C++ B组蓝桥杯省赛真题
|
6月前
|
算法 C++
小唐开始刷蓝桥(六)2015年第六届C/C++ B组蓝桥杯省赛真题
小唐开始刷蓝桥(六)2015年第六届C/C++ B组蓝桥杯省赛真题
|
6月前
|
数据安全/隐私保护 C++
小唐开始刷蓝桥(九)2012年第三届C/C++ B组蓝桥杯省赛真题
小唐开始刷蓝桥(九)2012年第三届C/C++ B组蓝桥杯省赛真题