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)
👨🏫 参考题解
#include<iostream>
#include<stdlib.h>
#include<time.h>
#include<cstdio>
#include<cmath>
using namespace std;
int tt,T=50;
double a,t0=100,t1,t2=1e-8,k=0.98;
double f(double x){return 6*x*x*x*x*x*x*x+8*x*x*x*x*x*x+7*x*x*x+5*x*x-a*x;
}
double rd(double x){return rand()*1.0/RAND_MAX*x;
}
int main()
{srand(time(NULL));double x,y,tx,ty,px,py;scanf("%d",&tt);while(tt--){scanf("%lf",&a);t1=t0;x=0;px=0;py=f(0);while(t1>t2){y=f(x);for(int i=1;i<=T;i++){tx=x+(rand()%2*2-1)*t1;if(tx<-0.01||tx>100.01) continue;ty=f(tx);if(ty<y){x=tx;y=ty;}else{if(rd(1)<exp((y-ty)/t1)){x=tx;y=ty;}}if(ty<py){px=tx;py=ty;}}t1=t1*k;}if(px<0.0) px=0.0;if(px>100.0) px=100.0;printf("%.4f\n",f(px));}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