GDPU 竞赛技能实践 天码行空7 排序 归并

1. 区间合并

在这里插入图片描述
输入

5
5 6
1 4
10 10
6 9
8 10

输出

1 4
5 10

💖 Main.java

import java.util.Arrays;
import java.util.Scanner;

public class Main
{
	static int N = 100010;
	static int n;

//	区间类
	static class Node
	{
		int l;// 区间左端点
		int r;// 区间右端点

		public Node(int l, int r)
		{
			this.l = l;
			this.r = r;
		}
	}

	public static void main(String[] args)
	{
//		输入区间数据
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		Node[] range = new Node[n];
		for (int i = 0; i < n; i++)
		{
			int l = sc.nextInt();
			int r = sc.nextInt();
			range[i] = new Node(l, r);
		}

//		数组按 区间左端点进行排序  
		Arrays.sort(range, (o1, o2) -> o1.l - o2.l);

//		连续被覆盖的大区间 [left,right]
		int left = range[0].l;
		int right = range[0].r;
		for (int i = 1; i < n; i++)
		{
//			 当前区间的左边界 <= 前一个连续大区间:两区间能衔接起来
			if (range[i].l <= right)
			{
				right = range[i].r;
			} else // 两区间衔接不上了
			{
				System.out.println(left + " " + right);// 输出前一个大区间
//				更新大区间的边界
				left = range[i].l;
				right = range[i].r;
			}
		}
		System.out.println(left + " " + right);// 输出最后一个大区间
	}

}

2. 模拟退火(SA)

👨‍🏫 题目地址
👨‍🏫 参考题解

💖 Cpp

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

const double eps = 1e-8;    // 终止温度

double y;
double func(double x)   // 计算函数值
{
    return 6 * pow(x, 7.0) + 8 * pow(x, 6.0) + 7 * pow(x, 3.0) + 5 * pow(x, 2.0) - y * x;
}

double solve(void)
{
    double T = 100;         // 初始温度
    double delta = 0.98;    // 降温系数
    double x = 50.0;        // x的初始值
    double now = func(x);   // 计算初始函数值
    double ans = now;       // 返回值
    while (T > eps) {
        int f[2] = {1, -1};
        double newx = x + f[rand() % 2] * T;    // 按概率改变x,随t的降温而减少
        if (newx >= 0 && newx <= 100) {
            double next = func(newx);
            ans = min(ans, next);
            if (now - next > eps) {
                x = newx;
                now = next;
            }
        }
        T *= delta;
    }
    return ans;
}

int main(void)
{
    int cas;
    scanf("%d", &cas);
    while (cas--) {
        scanf("%lf", &y);
        printf("%.4lf\n", solve());
    }
    return 0;
}

3. 谁在中间

在这里插入图片描述

💖 Main.java

import java.util.Arrays;
import java.util.Scanner;

public class Main
{
	static int N = (int) 1e5 + 10;
	static int[] a = new int[N];

	public static void main(String[] args)
	{
		Scanner sc = new Scanner(System.in);
//		输入
		int T = sc.nextInt();
		while (T-- > 0)
		{
			int n = sc.nextInt();
			for (int i = 0; i < n; i++)
				a[i] = sc.nextInt();
			Arrays.sort(a, 0, n);// 排序
			System.out.println(a[n >> 1]);// 取中间值
		}
	}
}

输入

1
5 1 2 4 5 3

输出

3

4. 求逆序对

在这里插入图片描述

💖 Main.java

归并求逆序对

import java.util.Scanner;

public class Main
{
	static int N = 100010;
	static int[] q = new int[N], tmp = new int[N];

	public static void main(String[] args)
	{
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int k = sc.nextInt();
		for (int i = 0; i < n; i++)
			q[i] = sc.nextInt();
		long cnt = mergeSort(0, n - 1);
		System.out.println(Math.max(0, cnt - k));
	}

	/**
	 * @param l 区间左边界
	 * @param r 区间右边界
	 * @return long 类型的区间内的逆序对
	 */
	private static long mergeSort(int l, int r)
	{
//		递归出口
		if (l >= r)
			return 0;// 区间只有一个数了,没有逆序队

//		分
		int mid = l + r >> 1;
		long res = mergeSort(l, mid) + mergeSort(mid + 1, r);

//		治 (归并)
		int k = 0;// 临时数组指针
		int i = l;// 左区间指针
		int j = mid + 1;// 右区间指针
		while (i <= mid && j <= r)
		{
			if (q[i] <= q[j])// 无逆序对
				tmp[k++] = q[i++];
			else
			{// 右边区间的数比左边区间的数小,有逆序对
				tmp[k++] = q[j++];
				res += mid - i + 1;
			}
		}
//		断后
		if (i <= mid)
			tmp[k++] = q[i++];
		if (j <= r)
			tmp[k++] = q[j++];

//		物归原主
		for (i = l, j = 0; i <= r; i++, j++)
		{
			q[i] = tmp[j];
		}

		return res;
	}
}

输入

3 1
2 2 1

输出

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值