2023-01-12:一个n*n的二维数组中,只有0和1两种值, 当你决定在某个位置操作一次, 那么该位置的行和列整体都会变成1,不管之前是什么状态。 返回让所有值全变成1,最少的操作次数。 1 <
2023-01-12:一个n*n的二维数组中,只有0和1两种值,
当你决定在某个位置操作一次,
那么该位置的行和列整体都会变成1,不管之前是什么状态。
返回让所有值全变成1,最少的操作次数。
1 < n < 10,没错!原题就是说n < 10, 不会到10!最多到9!
来自华为。
答案2023-01-12:
四维dp+贪心。这道题优化力度很有限,跟暴力差不多。
代码用rust和solidity编写。
代码用solidity编写。代码如下:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract Hello{
function main() public pure returns (int32){
int32[][] memory matrix = new int32[][](2);
for (int32 i = 0; i < 2; i++) {
matrix[uint32(i)] = new int32[](2);
for (int32 j = 0; j < 2; j++) {
matrix[uint32(i)][uint32(j)] = 0;
}
}
matrix[1][1] = 1;
int32 ans = setOneMinTimes3(matrix);
return ans;
}
// 正式方法 + 贪心
function setOneMinTimes3(int32[][] memory matrix) public pure returns (int32) {
int32 n = int32(uint32(matrix.length));
int32 m = int32(uint32(matrix[0].length));
int32[] memory arr = new int32[](uint32(n));
for (int32 i = 0; i < n; i++) {
int32 status = 0;
for (int32 j = 0; j < m; j++) {
if (matrix[uint32(i)][uint32(j)] == 1) {
status |= leftk(j);
}
}
arr[uint32(i)] = status;
}
int32[][][][] memory dp = new int32[][][][](uint32(leftk(n)));
for (int32 a = 0; a < leftk(n); a++) {
dp[uint32(a)] = new int32[][][](uint32(leftk(m)));
for (int32 b = 0; b < leftk(m); b++) {
dp[uint32(a)][uint32(b)] = new int32[][](uint32(n));
for (int32 c = 0; c < n; c++) {
dp[uint32(a)][uint32(b)] [uint32(c)] = new int32[](uint32(m));
for (int32 d = 0; d < m; d++) {
dp[uint32(a)][uint32(b)] [uint32(c)][uint32(d)] = -1;
}
}
}
}
return process3(arr, n, m, 0, 0, 0, 0, dp);
}
function process3(int32[] memory arr, int32 n, int32 m, int32 row, int32 col, int32 r, int32 c, int32[][][][] memory dp) public pure returns (int32) {
if (r == n) {
for (int32 i = 0; i < n; i++) {
if ((row & leftk(i)) == 0 && (arr[uint32(i)] | col) != leftk(m) - 1) {
return 2147483647;
}
}
return 0;
}
if (c == m) {
return process3(arr, n, m, row, col, r + 1, 0, dp);
}
if (dp[uint32(row)][uint32(col)][uint32(r)][uint32(c)] != -1) {
return dp[uint32(row)][uint32(col)][uint32(r)][uint32(c)];
}
int32 p1 = process3(arr, n, m, row, col, r, c + 1, dp);
int32 p2 = 2147483647;
int32 next2 = process3(arr, n, m, row | leftk(r), col | leftk(c), r + 1, 0, dp);
if (next2 != 2147483647) {
p2 = 1 + next2;
}
int32 ans = min(p1, p2);
dp[uint32(row)][uint32(col)][uint32(r)][uint32(c)] = ans;
return ans;
}
function leftk(int32 k) public pure returns (int32){
int32 ans = 1;
while (k>0){
ans*=2;
k--;
}
return ans;
}
function min(int32 a,int32 b)public pure returns (int32){
if(a<b){
return a;
}else{
return b;
}
}
}

代码用rust编写。代码如下:
use rand::Rng;
use std::iter::repeat;
fn main() {
let mut matrix = vec![vec![0, 0], vec![0, 1]];
let ans3 = set_one_min_times3(&mut matrix);
println!("ans3 = {}", ans3);
let nn: i32 = 3;
let test_time: i32 = 5000;
println!("测试开始");
for i in 0..test_time {
let n = rand::thread_rng().gen_range(0, nn) + 1;
let m = rand::thread_rng().gen_range(0, nn) + 1;
let p0 = rand::thread_rng().gen_range(0, 100);
let mut matrix = random_matrix(n, m, p0);
let ans1 = set_one_min_times1(&mut matrix);
let ans2 = set_one_min_times2(&mut matrix);
let ans3 = set_one_min_times3(&mut matrix);
if ans1 != ans2 || ans1 != ans3 {
println!("出错了!{}", i);
println!("ans1 = {}", ans1);
println!("ans2 = {}", ans2);
println!("ans3 = {}", ans3);
break;
}
}
println!("测试结束");
}
// 暴力方法
// 为了验证
fn set_one_min_times1(matrix: &mut Vec<Vec<i32>>) -> i32 {
let n = matrix.len() as i32;
let m = matrix[0].len() as i32;
let limit = 1 << (n * m);
let mut ans = i32::MAX;
// 0000000000000
// 0000000000001
// 0000000000010
// 0000000000011
// 0000000000100
for status in 0..limit {
if ok(status, matrix, n, m) {
ans = get_min(ans, hamming_weight(status));
}
}
return ans;
}
fn get_min<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T {
if a < b {
a
} else {
b
}
}
fn ok(status: i32, matrix: &mut Vec<Vec<i32>>, n: i32, m: i32) -> bool {
let mut help: Vec<Vec<i32>> = repeat(repeat(0).take(m as usize).collect())
.take(n as usize)
.collect();
let limit = n * m;
for i in 0..limit {
if (status & (1 << i)) != 0 {
let row = i / m;
let col = i % m;
for j in 0..n {
help[j as usize][col as usize] = 1;
}
for j in 0..m {
help[row as usize][j as usize] = 1;
}
}
}
for i in 0..n {
for j in 0..m {
if help[i as usize][j as usize] == 0 && matrix[i as usize][j as usize] == 0 {
return false;
}
}
}
return true;
}
fn hamming_weight(n: i32) -> i32 {
let mut n = n as u32;
n = (n & 0x55555555) + ((n >> 1) & 0x55555555);
n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
n = (n & 0x0f0f0f0f) + ((n >> 4) & 0x0f0f0f0f);
n = (n & 0x00ff00ff) + ((n >> 8) & 0x00ff00ff);
n = (n & 0x0000ffff) + ((n >> 16) & 0x0000ffff);
return n as i32;
}
// 正式方法
fn set_one_min_times2(matrix: &mut Vec<Vec<i32>>) -> i32 {
let n = matrix.len() as i32;
let m = matrix[0].len() as i32;
let mut arr: Vec<i32> = repeat(0).take(n as usize).collect();
for i in 0..n {
let mut status = 0;
for j in 0..m {
if matrix[i as usize][j as usize] == 1 {
status |= 1 << j;
}
}
arr[i as usize] = status;
}
let mut dp: Vec<Vec<Vec<Vec<i32>>>> = repeat(
repeat(
repeat(repeat(-1).take(m as usize).collect())
.take(n as usize)
.collect(),
)
.take((1 << m) as usize)
.collect(),
)
.take((1 << n) as usize)
.collect();
return process2(&mut arr, n, m, 0, 0, 0, 0, &mut dp);
}
fn process2(
arr: &mut Vec<i32>,
n: i32,
m: i32,
row: i32,
col: i32,
r: i32,
c: i32,
dp: &mut Vec<Vec<Vec<Vec<i32>>>>,
) -> i32 {
if r == n {
for i in 0..n {
if (row & (1 << i)) == 0 && (arr[i as usize] | col) != (1 << m) - 1 {
return i32::MAX;
}
}
return 0;
}
if c == m {
return process2(arr, n, m, row, col, r + 1, 0, dp);
}
if dp[row as usize][col as usize][r as usize][c as usize] != -1 {
return dp[row as usize][col as usize][r as usize][c as usize];
}
let p1 = process2(arr, n, m, row, col, r, c + 1, dp);
let mut p2 = i32::MAX;
let next2 = process2(arr, n, m, row | (1 << r), col | (1 << c), r, c + 1, dp);
if next2 != i32::MAX {
p2 = 1 + next2;
}
let ans = get_min(p1, p2);
dp[row as usize][col as usize][r as usize][c as usize] = ans;
return ans;
}
// 正式方法 + 贪心
fn set_one_min_times3(matrix: &mut Vec<Vec<i32>>) -> i32 {
let n = matrix.len() as i32;
let m = matrix[0].len() as i32;
let mut arr: Vec<i32> = repeat(0).take(n as usize).collect();
for i in 0..n {
let mut status = 0;
for j in 0..m {
if matrix[i as usize][j as usize] == 1 {
status |= 1 << j;
}
}
arr[i as usize] = status;
}
let mut dp: Vec<Vec<Vec<Vec<i32>>>> = repeat(
repeat(
repeat(repeat(-1).take(m as usize).collect())
.take(n as usize)
.collect(),
)
.take((1 << m) as usize)
.collect(),
)
.take((1 << n) as usize)
.collect();
return process3(&mut arr, n, m, 0, 0, 0, 0, &mut dp);
}
fn process3(
arr: &mut Vec<i32>,
n: i32,
m: i32,
row: i32,
col: i32,
r: i32,
c: i32,
dp: &mut Vec<Vec<Vec<Vec<i32>>>>,
) -> i32 {
if r == n {
for i in 0..n {
if (row & (1 << i)) == 0 && (arr[i as usize] | col) != (1 << m) - 1 {
return i32::MAX;
}
}
return 0;
}
if c == m {
return process3(arr, n, m, row, col, r + 1, 0, dp);
}
if dp[row as usize][col as usize][r as usize][c as usize] != -1 {
return dp[row as usize][col as usize][r as usize][c as usize];
}
let p1 = process3(arr, n, m, row, col, r, c + 1, dp);
let mut p2 = i32::MAX;
let next2 = process3(arr, n, m, row | (1 << r), col | (1 << c), r + 1, 0, dp);
if next2 != i32::MAX {
p2 = 1 + next2;
}
let ans = get_min(p1, p2);
dp[row as usize][col as usize][r as usize][c as usize] = ans;
return ans;
}
fn random_matrix(n: i32, m: i32, p0: i32) -> Vec<Vec<i32>> {
let mut ans: Vec<Vec<i32>> = repeat(repeat(0).take(m as usize).collect())
.take(n as usize)
.collect();
for i in 0..n {
for j in 0..m {
ans[i as usize][j as usize] = if rand::thread_rng().gen_range(0, 100) < p0 {
0
} else {
1
};
}
}
return ans;
}

2023-01-12:一个n*n的二维数组中,只有0和1两种值, 当你决定在某个位置操作一次, 那么该位置的行和列整体都会变成1,不管之前是什么状态。 返回让所有值全变成1,最少的操作次数。 1 <的更多相关文章
- 《剑指Offer》第1题(Java实现):在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
一.题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该 ...
- 功能要求:定义一个两行三列的二维数组 names 并赋值,使用二重循环输出二维数组中的元素。
功能要求:定义一个两行三列的二维数组 names 并赋值,使用二重循环输出二维数组中的元素 names={{"tom","jack","mike&qu ...
- 剑指offer系列——二维数组中,每行从左到右递增,每列从上到下递增,设计算法找其中的一个数
题目:二维数组中,每行从左到右递增,每列从上到下递增,设计一个算法,找其中的一个数 分析: 二维数组这里把它看作一个矩形结构,如图所示: 1 2 8 2 4 9 12 4 7 10 13 6 8 11 ...
- 剑指offer-特定二维数组中查找一个元素是否存在-二分搜索-二维数组
int [][] array ={ {1,2,8,9}, {2,4,9,12}, {4,7,10,13}, {6,8,11,19} }; 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都 ...
- 【c语言】二维数组中的查找,杨氏矩阵在一个二维数组中,每行都依照从左到右的递增的顺序排序,输入这种一个数组和一个数,推断数组中是否包括这个数
// 二维数组中的查找,杨氏矩阵在一个二维数组中.每行都依照从左到右的递增的顺序排序. // 每列都依照从上到下递增的顺序排序.请完毕一个函数,输入这种一个数组和一个数.推断数组中是否包括这个数 #i ...
- 【剑指Offer】01、二维数组中的查找
题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数 ...
- C语言:将3*5矩阵中第k列的元素左移到第0列,第k列以后的每列元素依次左移,原来左边的各列依次绕到右边。-在m行m列的二维数组中存放如下规律的数据,
//将3*5矩阵中第k列的元素左移到第0列,第k列以后的每列元素依次左移,原来左边的各列依次绕到右边. #include <stdio.h> #define M 3 #define N 5 ...
- 062 01 Android 零基础入门 01 Java基础语法 07 Java二维数组 01 二维数组应用
062 01 Android 零基础入门 01 Java基础语法 07 Java二维数组 01 二维数组应用 本文知识点:二维数组应用 二维数组的声明和创建 ? 出现空指针异常 数组的名字指向数组的第 ...
- 【剑指offer】01 二维数组中的查找
题目地址:二维数组中的查找 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照 ...
- 将String类型的二维数组中的元素用FileOutputStream的write方法生成一个文件
将String类型的二维数组中的元素用FileOutputStream的write方法生成一个文件import java.io.File;import java.io.FileOutputStre ...
随机推荐
- conda环境下使用nvcc -V报错nvcc: command not found的一种解决方法
前言 缘起 实验室的学弟问我为什么他使用nvcc命令报错,起先我以为他用的是老师给的root账户,按照参考文献1便可以解决问题. 但由于并非root用户,/usr/local下没有cuda,于是便 ...
- Kafka 事务
更多内容,前往IT-BLOG 在了解 Kafka的事务之前,先说一下 Kafka中幂等和事务(Kafka 0.11.0.0版本引入的两个特性)以此来实现 Exactly once(精确一次)了解更多链 ...
- ChatGPT能给IOT行业带来哪些改变
引言 随着移动互联网.传感器的发展,移动互联的潮流逐渐转移到物联网行业,每个设备成为了物联网连接的终端. 与传统的设备相比,智能设备最突出的特点就是智能化.目前,在市场上的智能设备通过智能程序设定或者 ...
- 论文解读(CosFace)《CosFace: Large Margin Cosine Loss for Deep Face Recognition》
论文信息 论文标题:CosFace: Large Margin Cosine Loss for Deep Face Recognition论文作者:H. Wang, Yitong Wang, Zhen ...
- SpringBoot打包成exe(别再用exe4j了,使用JDK自带工具)
SpringBoot打包成exe(别再用exe4j了,使用JDK自带工具) 搜到大部分打包exe的文章都是使用exe4j打包 步骤贼多,安装麻烦,打包麻烦 收费软件,公司使用会吃律师函 JDK14以上 ...
- 在react中使用wangEditorV5
wangEditor是基于JavaScript和css的一款web富文本编辑器,是国内比较好用的一款轻量级富文本编辑器,上手简单,易用且开源免费. 官方文档:http://www.wangeditor ...
- [Linux]常用命令之【history】#查看历史操作#
1 历史记录: history history命令就是历史记录. 它显示了在终端中所执行过的所有命令的历史. history //显示终端执行过的命令 history 10 //显示最近10条终端执行 ...
- [Linux]命令行分类
0 操作系统 / 编译 / 进程 / 内存 / 硬盘 / 硬件 hostname / hostnamectl / uname hostnamectl set-hostname xxxx 重置hostn ...
- Hugging News #0407: Google AI 的 Pix2Struct 来啦、开发者资源页面发布
每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...
- java 回行矩阵的打印
n=3 n=4 1 2 3 1 2 3 4 8 9 4 12 13 14 5 7 6 5 11 16 15 6 10 9 ...