经典算法Golang实现

发布于:2025-04-02 ⋅ 阅读:(22) ⋅ 点赞:(0)

负一、写在前面

零、前置

一、基础算法

0. 内容概要

包括排序、二分、前缀和、差分、双指针、离散化、区间和

1. 排序

(1)快速排序

package main

import "fmt"

func QuickSort(arr []int, l int, r int) {
	if l >= r {
		return
	}

	x, i, j := arr[(l+r)/2], l-1, r+1

	for i < j {
		for {
			i++
			if arr[i] >= x {
				break
			}
		}

		for {
			j--
			if arr[j] <= x {
				break
			}
		}

		if i < j {
			arr[i], arr[j] = arr[j], arr[i]
		}
	}

	QuickSort(arr, l, j)
	QuickSort(arr, j+1, r)
}

func main() {
	var n int
	fmt.Scanln(&n)

	arr := make([]int, n+5)

	for i := 0; i < n; i++ {
		fmt.Scan(&arr[i])
	}

	QuickSort(arr, 0, n-1)

	for i := 0; i < n; i++ {
		fmt.Printf("%d ", arr[i])
	}
}

(2)归并排序

package main

import "fmt"

// https://www.acwing.com/problem/content/789/

func MergeSort(arr []int, l int, r int) {
	if l >= r {
		return
	}

	mid := (l + r) / 2
	MergeSort(arr, l, mid)
	MergeSort(arr, mid+1, r)

	tmp := make([]int, r-l+1)
	i, j, k := l, mid+1, 0

	for i <= mid && j <= r {
		if arr[i] < arr[j] {
			tmp[k] = arr[i]
			k++
			i++
		} else {
			tmp[k] = arr[j]
			k++
			j++
		}
	}

	for i <= mid {
		tmp[k] = arr[i]
		k++
		i++
	}

	for j <= r {
		tmp[k] = arr[j]
		k++
		j++
	}

	k = 0
	for i := l; i <= r; i++ {
		arr[i] = tmp[k]
		k++
	}
}

func main() {
	var n int
	fmt.Scanln(&n)

	arr := make([]int, n+5)

	for i := 0; i < n; i++ {
		fmt.Scan(&arr[i])
	}

	MergeSort(arr, 0, n-1)

	for i := 0; i < n; i++ {
		fmt.Printf("%d ", arr[i])
	}
}

2. 二分

(1)整数二分

package main

import "fmt"

// https://www.acwing.com/problem/content/791/
func main() {
	var n, q int
	fmt.Scanf("%d %d", &n, &q)

	arr := make([]int, n+5)
	for i := 0; i < n; i++ {
		fmt.Scan(&arr[i])
	}

	var x int
	for q > 0 {
		fmt.Scanln(&x)

		l, r := 0, n-1

		for l < r {
			mid := (l + r) / 2
			if arr[mid] < x {
				l = mid + 1
			} else {
				r = mid
			}
		}
		q--
		if arr[l] != x {
			fmt.Println("-1 -1")
			continue
		}

		fmt.Print(l)

		l, r = 0, n-1
		for l < r {
			mid := (l + r + 1) / 2
			if arr[mid] > x {
				r = mid - 1
			} else {
				l = mid
			}
		}

		fmt.Printf(" %d\n", l)

	}
}

(2)浮点数二分

package main

import "fmt"

// https://www.acwing.com/problem/content/792/
func main() {
	var n float64
	fmt.Scanln(&n)

	l, r := -1000.00, 1000.00
	for r-l > 1e-7 {
		mid := (l + r) / 2
		if mid*mid*mid > n {
			r = mid
		} else {
			l = mid
		}
	}

	fmt.Printf("%.6f", l)
}

3. 前缀和

(1)一维前缀和

package main

import "fmt"

// https://www.acwing.com/problem/content/797/
func main() {
	var n, m int
	fmt.Scanf("%d %d", &n, &m)

	a := make([]int, n+5)
	sa := make([]int, n+5)
	for i := 1; i <= n; i++ {
		fmt.Scan(&a[i])
		sa[i] = sa[i-1] + a[i]
	}

	var l, r int
	for m > 0 {
		fmt.Scanf("%d %d", &l, &r)
		fmt.Println(sa[r] - sa[l-1])
		m--
	}
}

(2)二维前缀和

package main

import (
	"bufio"
	"fmt"
	"os"
)

// https://www.acwing.com/problem/content/description/798/
func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	var n, m, q int
	fmt.Scanf("%d %d %d", &n, &m, &q)

	a := make([][]int, n+1)
	sa := make([][]int, n+1)

	for i := 0; i <= n; i++ {
		a[i] = make([]int, m+1)
		sa[i] = make([]int, m+1)
	}

	for i := 1; i <= n; i++ {
		for j := 1; j <= m; j++ {
			fmt.Fscan(in, &a[i][j])
			sa[i][j] = sa[i-1][j] + sa[i][j-1] - sa[i-1][j-1] + a[i][j]
		}
	}

	var x1, y1, x2, y2 int
	for q > 0 {
		fmt.Fscan(in, &x1, &y1, &x2, &y2)
		fmt.Fprintln(out, sa[x2][y2]-sa[x2][y1-1]-sa[x1-1][y2]+sa[x1-1][y1-1])
		q--
	}
}

4. 差分

(1)一维差分

package main

import (
	"bufio"
	"fmt"
	"os"
)

// https://www.acwing.com/problem/content/799/

func main() {
	in := bufio.NewReader(os.Stdin)
	//out := bufio.NewWriter(os.Stdout)

	var n, q int
	fmt.Scan(&n, &q)

	a := make([]int, n+5)
	sa := make([]int, n+5)

	for i := 1; i <= n; i++ {
		fmt.Fscan(in, &a[i])
		sa[i] += a[i]
		sa[i+1] -= a[i]
	}

	var l, r, c int
	for q > 0 {
		fmt.Fscan(in, &l, &r, &c)
		sa[l] += c
		sa[r+1] -= c
		q--
	}

	for i := 1; i <= n; i++ {
		sa[i] += sa[i-1]
		fmt.Printf("%d ", sa[i])
	}

}

(2)二维差分

package main

import (
	"bufio"
	"fmt"
	"os"
)

// https://www.acwing.com/problem/content/description/800/
func insert(a [][]int, x1, y1, x2, y2, c int) {
	a[x1][y1] += c
	a[x2+1][y1] -= c
	a[x1][y2+1] -= c
	a[x2+1][y2+1] += c
}

func main() {
	in := bufio.NewReader(os.Stdin)

	var n, m, q int
	fmt.Scan(&n, &m, &q)

	a := make([][]int, n+2)
	for i := 0; i <= n+1; i++ {
		a[i] = make([]int, m+2)
	}

	var x int
	for i := 1; i <= n; i++ {
		for j := 1; j <= m; j++ {
			fmt.Fscan(in, &x)
			insert(a, i, j, i, j, x)
		}
	}

	var x1, y1, x2, y2 int
	for q > 0 {
		fmt.Fscan(in, &x1, &y1, &x2, &y2, &x)

		insert(a, x1, y1, x2, y2, x)
		q--
	}

	for i := 1; i <= n; i++ {
		for j := 1; j <= m; j++ {
			a[i][j] += a[i-1][j] + a[i][j-1] - a[i-1][j-1]
		}
	}

	for i := 1; i <= n; i++ {
		for j := 1; j <= m; j++ {
			fmt.Printf("%d ", a[i][j])
		}
		fmt.Println()
	}

}

5. 合并区间

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

//https://www.acwing.com/problem/content/description/805/

type seg struct {
	l int
	r int
}

func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	var n int
	fmt.Fscan(in, &n)
	a := make([]seg, n)

	for i := 0; i < n; i++ {
		fmt.Fscan(in, &a[i].l, &a[i].r)
	}

	sort.Slice(a,
		func(i, j int) bool {
			return a[i].l <= a[j].l
		})

	ans := 0
	st, ed := a[0].l, a[0].r
	for i := 1; i < n; i++ {
		now := a[i]
		if ed < now.l {
			ans++
			st = now.l
			ed = now.r
		} else {
			st = st
			if ed < now.r {
				ed = now.r
			}
		}
	}

	fmt.Println(ans + 1)
}

二、数据结构

0. 内容概要

包括并查集、树状数组、线段树

三、搜索与图论

0. 内容概要

包括DFS、BFS、最短路、拓扑排序、最小生成树、LCA

四、数论

0. 内容概要

包括试除法、埃氏筛、gcd与lcm、快速幂与逆元、组合数

五、动态规划

0. 内容概要

包括背包问题、线性DP、区间DP、树形DP


网站公告

今日签到

点亮在社区的每一天
去签到