首页 > 其他分享 >2024-01-24:用go语言,已知一个n*n的01矩阵, 只能通过通过行交换、或者列交换的方式调整矩阵, 判断这个矩阵的对角线是否能全为1,如果能返回true,不能返回false。 我们升级一下:

2024-01-24:用go语言,已知一个n*n的01矩阵, 只能通过通过行交换、或者列交换的方式调整矩阵, 判断这个矩阵的对角线是否能全为1,如果能返回true,不能返回false。 我们升级一下:

时间:2024-01-24 10:11:25浏览次数:37  
标签:返回 01 slack int graph 矩阵 ++ lx match

2024-01-24:用go语言,已知一个n*n的01矩阵,

只能通过通过行交换、或者列交换的方式调整矩阵,

判断这个矩阵的对角线是否能全为1,如果能返回true,不能返回false。

我们升级一下:

已知一个n*n的01矩阵,

只能通过通过行交换、或者列交换的方式调整矩阵,

判断这个矩阵的对角线是否能全为1,如果不能打印-1。

如果能,打印需要交换的次数,并且打印怎么交换。

来自网易。

答案2024-01-24:

来自左程云

灵捷3.5

大体步骤如下:

1.遍历矩阵的每一行和每一列,统计每行和每列的1的个数。

2.如果某一行或某一列的1的个数超过n/2(n为矩阵的大小),则无法通过交换操作使得对角线上的元素全为1,直接输出-1。

3.创建一个长度为n的数组rowOnes和colOnes,分别存储每行和每列的1的个数。

4.创建一个长度为n的二维数组swap,用于记录交换操作。

5.从第一行开始,逐行遍历矩阵,对于每一行,检查是否需要进行交换:

  • 如果该行的1的个数小于n/2,则说明需要进行行交换,找到一行与其交换,并更新swap数组。

6.接着从第一列开始,逐列遍历矩阵,对于每一列,检查是否需要进行交换:

  • 如果该列的1的个数小于n/2且当前行没有进行过行交换,则说明需要进行列交换,找到一列与其交换,并更新swap数组。

7.最后,检查矩阵的对角线是否全为1:

  • 逐行遍历矩阵,如果某一行的对角线元素不为1,则说明无法满足条件,输出-1。

8.如果能够满足条件,则输出交换次数k和交换操作:

  • 遍历swap数组,输出每次交换的行号和列号。

总的时间复杂度为O(n^2),其中n为矩阵的大小。

总的额外空间复杂度为O(n),用于存储rowOnes、colOnes和swap数组。

go完整代码如下:

package main

import (
	"fmt"
)

var out [1000][2]int

func main() {

	inputs := []int{2,
		0, 1,
		1, 0,
		2,
		1, 0,
		1, 0}
	ii := 0
	n := inputs[ii]
	ii++

	graph := make([][]int, n)
	for i := 0; i < n; i++ {
		graph[i] = make([]int, n)
		for j := 0; j < n; j++ {
			graph[i][j] = inputs[ii]
			ii++
		}
	}

	t := km(graph)
	fmt.Println(t)
	for i := 0; i < t; i++ {
		fmt.Printf("R %d %d\n", out[i][0]+1, out[i][1]+1)
	}

}

func km(graph [][]int) int {
	N := len(graph)
	lx := make([]int, N)
	ly := make([]int, N)
	match := make([]int, N)
	x := make([]bool, N)
	y := make([]bool, N)
	slack := make([]int, N)
	invalid := int(1e9)

	for i := 0; i < N; i++ {
		match[i] = -1
		lx[i] = -invalid
		for j := 0; j < N; j++ {
			lx[i] = max(lx[i], graph[i][j])
		}
		ly[i] = 0
	}

	for from := 0; from < N; from++ {
		for i := 0; i < N; i++ {
			slack[i] = invalid
		}
		fillBoolSlice(x, false)
		fillBoolSlice(y, false)

		for !dfs(from, x, y, lx, ly, match, slack, graph) {
			d := invalid
			for i := 0; i < N; i++ {
				if !y[i] && slack[i] < d {
					d = slack[i]
				}
			}
			for i := 0; i < N; i++ {
				if x[i] {
					lx[i] -= d
				}
				if y[i] {
					ly[i] += d
				}
			}
			fillBoolSlice(x, false)
			fillBoolSlice(y, false)
		}
	}

	ans := 0
	for i := 0; i < N; i++ {
		ans += (lx[i] + ly[i])
	}
	if ans < N {
		return -1
	}

	t := 0
	for i := 0; i < N; i++ {
		u, v := match[i], i
		if u != v {
			out[t][0] = v
			out[t][1] = u
			for j := i + 1; j < N; j++ {
				if match[j] == v {
					match[j] = u
				}
			}
			t++
		}
	}

	return t
}

func dfs(from int, x, y []bool, lx, ly, match, slack []int, graph [][]int) bool {
	N := len(graph)
	x[from] = true
	for to := 0; to < N; to++ {
		if !y[to] {
			d := lx[from] + ly[to] - graph[from][to]
			if d != 0 {
				slack[to] = min(slack[to], d)
			} else {
				y[to] = true
				if match[to] == -1 || dfs(match[to], x, y, lx, ly, match, slack, graph) {
					match[to] = from
					return true
				}
			}
		}
	}
	return false
}

func fillBoolSlice(arr []bool, value bool) {
	for i := 0; i < len(arr); i++ {
		arr[i] = value
	}
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

在这里插入图片描述

python代码如下:

# -*-coding:utf-8-*-
def km(graph):
    N = len(graph)
    lx = [-float('inf')] * N
    ly = [0] * N
    match = [-1] * N
    x = [False] * N
    y = [False] * N
    slack = [float('inf')] * N
    invalid = int(1e9)

    for i in range(N):
        lx[i] = max(graph[i])

    for from_ in range(N):
        for i in range(N):
            slack[i] = invalid
        x = [False] * N
        y = [False] * N

        while not dfs(from_, x, y, lx, ly, match, slack, graph):
            d = invalid
            for i in range(N):
                if not y[i] and slack[i] < d:
                    d = slack[i]
            for i in range(N):
                if x[i]:
                    lx[i] -= d
                if y[i]:
                    ly[i] += d
            x = [False] * N
            y = [False] * N

    ans = 0
    for i in range(N):
        ans += (lx[i] + ly[i])
    if ans < N:
        return -1

    t = 0
    out = [[0, 0]] * N
    for i in range(N):
        u, v = match[i], i
        if u != v:
            out[t][0] = v
            out[t][1] = u
            for j in range(i + 1, N):
                if match[j] == v:
                    match[j] = u
            t += 1

    return t, out


def dfs(from_, x, y, lx, ly, match, slack, graph):
    N = len(graph)
    x[from_] = True
    for to in range(N):
        if not y[to]:
            d = lx[from_] + ly[to] - graph[from_][to]
            if d != 0:
                slack[to] = min(slack[to], d)
            else:
                y[to] = True
                if match[to] == -1 or dfs(match[to], x, y, lx, ly, match, slack, graph):
                    match[to] = from_
                    return True
    return False


inputs = [2, 0, 1, 1, 0, 2, 1, 0, 1, 0]
ii = 0
n = inputs[ii]
ii += 1

graph = [[0] * n for _ in range(n)]
for i in range(n):
    for j in range(n):
        graph[i][j] = inputs[ii]
        ii += 1

t, out = km(graph)
print(t)
for i in range(t):
    print("R", out[i][0] + 1, out[i][1] + 1)

在这里插入图片描述

标签:返回,01,slack,int,graph,矩阵,++,lx,match
From: https://www.cnblogs.com/moonfdd/p/17984000

相关文章

  • adb命令补充---20240124
    1、如何查看系统是32位还是64位?adbshellgetpropro.product.cpu.abi---返回设备当前CPU的ABI版本号若结果包含"armv7-a"字样,则说明设备是32位;若结果包含"arm64-v8a"字样,则说明设备是64位。如何检测Android应用是32位还是64位?与32位系统不同的是,在64系统中会同时存在两个Zyg......
  • 【2024-01-23】增肌保养
    20:00是的春天需要你。经常会有一颗星,等着你抬头去看。                                                 ——里尔克这两天挺冷的,不过有了上个月十几天的速冻经验,衣着......
  • 【2024-01-22】回乡所闻
    20:00我的意识中,母亲像一棵树,父亲像一座山。他们教育我很多朴素的为人处世的道理,令我终生受益。我觉得,对于每一个人,父母早期的家教都具有初级的朴素的人文元素。                                    ......
  • 算法模板 v1.3.2.20240124
    算法模板v1.1.1.20240115:之前的历史版本已经不可寻,创建了第一份算法模板。v1.2.1.20240116:删除“编译”-“手动开栈”与“编译”-“手动开O优化”;将“编译”-“CF模板”中的第20行代码cin>>T;注释;删除“读写”及其目录下的内容;删除“图论”-“欧拉图”-“混合图”;删除“图论”-......
  • 2024-01-23 闲话。
    总结一下最近想到的事情:闲话Novelty制胜。有乐子就能满足人们猎奇的需求,“山朗润起来了,水涨起来了,太阳的脸红起来了。”这种内容没有流量效应,受众太少production,平铺直叙感觉也没什么意思,最近在bilibili上看到一个叫做Zhao_Song的up主,满足了我对“我能解答的”谜语的......
  • 19_Java流程控制01-Scanner进阶使用
    Scanner进阶使用整数:hasNextInt()——nextInt()小数:hasNextFloat()——nextFloat()if:判断语句while:循环语句练习:循环输入,求和与平均数,回车确认,非数字结束指令并输出结果。Scannerscanner=newScanner(System.in);//开始doublesum=0;intm=0;System.out.println("请输......
  • 百度网盘(百度云)SVIP超级会员共享账号每日更新(2024.01.23)
    一、百度网盘SVIP超级会员共享账号可能很多人不懂这个共享账号是什么意思,小编在这里给大家做一下解答。我们多知道百度网盘很大的用处就是类似U盘,不同的人把文件上传到百度网盘,别人可以直接下载,避免了U盘的物理载体,直接在网上就实现文件传输。百度网盘SVIP会员可以让自己百度账......
  • APIO2014 回文串
    APIO2014回文串decription给定一个长度为\(n\)的字符串\(S\)。求其所有回文子串中出现次数乘上长度的最大值。\(n\leq3\times10^5\)solution根据经典结论,长度为\(n\)的字符串的本质不同回文子串个数不超过\(n\)个,我们可以找出所有本质不同回文子串,然后计算它们的......
  • 2024.01 总结
    1.模拟赛总的来说状态较好,只有一次较大的挂分。1-1.优点:思维方面:能够推出DP式子,通过打表找到一些规律。码力方面:基础的数据结构实现很少出错。策略方面:先把自己能拿的分拿满。1-2.缺点:思维方面:推出式子不会优化。码力方面:难以实现复杂的数据结构和代码。......
  • 0123今日收获
    今日代码1今日代码2今日代码3今日代码4今日代码5今日代码6今日代码7今日代码8今日代码9!今日收获满满......