当前位置:网站首页>2022-06-12:在N*N的正方形棋盤中,有N*N個棋子,那麼每個格子正好可以擁有一個棋子。 但是現在有些棋子聚集到一個格子上了,比如: 2 0 3 0 1 0 3 0 0 如上的二維數組代錶,一
2022-06-12:在N*N的正方形棋盤中,有N*N個棋子,那麼每個格子正好可以擁有一個棋子。 但是現在有些棋子聚集到一個格子上了,比如: 2 0 3 0 1 0 3 0 0 如上的二維數組代錶,一
2022-06-13 06:50:00 【福大大架構師每日一題】
2022-06-12:在NN的正方形棋盤中,有NN個棋子,那麼每個格子正好可以擁有一個棋子。
但是現在有些棋子聚集到一個格子上了,比如:
2 0 3
0 1 0
3 0 0
如上的二維數組代錶,一共3*3個格子,
但是有些格子有2個棋子、有些有3個、有些有1個、有些沒有,
請你用棋子移動的方式,讓每個格子都有一個棋子,
每個棋子可以上、下、左、右移動,每移動一步算1的代價。
返回最小的代價。
來自微軟。
答案2022-06-12:
km算法,距離取負數。
代碼用rust編寫。代碼如下:
use rand::Rng;
fn main() {
let len: i32 = 4;
let test_time: i32 = 1000;
println!("測試開始");
for _ in 0..test_time {
let mut graph = random_valid_matrix(len);
let ans1 = min_distance1(&mut graph);
let ans2 = min_distance2(&mut graph);
if ans1 != ans2 {
println!("出錯了!");
println!("ans1 = {}", ans1);
println!("ans2 = {}", ans2);
println!("===============");
}
}
println!("測試結束");
}
// 暴力解
// 作為對數器
fn min_distance1(map: &mut Vec<Vec<i32>>) -> i32 {
let mut n = 0;
let mut m = 0;
for i in 0..map.len() as i32 {
for j in 0..map[0].len() as i32 {
n += get_max(0, map[i as usize][j as usize] - 1);
m += if map[i as usize][j as usize] == 0 {
1
} else {
0
};
}
}
if n != m || n == 0 {
return 0;
}
let mut nodes: Vec<Vec<i32>> = vec![];
for i in 0..n {
nodes.push(vec![]);
for _ in 0..2 {
nodes[i as usize].push(0);
}
}
let mut space: Vec<Vec<i32>> = vec![];
for i in 0..m {
space.push(vec![]);
for _ in 0..2 {
space[i as usize].push(0);
}
}
n = 0;
m = 0;
for i in 0..map.len() as i32 {
for j in 0..map[0].len() as i32 {
for _k in 2..map[i as usize][j as usize] {
nodes[n as usize][0] = i;
nodes[n as usize][1] = j;
n += 1;
}
if map[i as usize][j as usize] == 0 {
space[m as usize][0] = i;
space[m as usize][1] = j;
m += 1;
}
}
}
return process1(&mut nodes, 0, &mut space);
}
fn process1(nodes: &mut Vec<Vec<i32>>, index: i32, space: &mut Vec<Vec<i32>>) -> i32 {
let mut ans = 0;
if index == nodes.len() as i32 {
for i in 0..nodes.len() as i32 {
ans += distance(&mut nodes[i as usize], &mut space[i as usize]);
}
} else {
ans = 2147483647;
for i in index..nodes.len() as i32 {
swap(nodes, index, i);
ans = get_min(ans, process1(nodes, index + 1, space));
swap(nodes, index, i);
}
}
return ans;
}
fn swap(nodes: &mut Vec<Vec<i32>>, i: i32, j: i32) {
let tmp = nodes[i as usize].clone();
nodes[i as usize] = nodes[j as usize].clone();
nodes[j as usize] = tmp.clone();
}
fn distance(a: &mut Vec<i32>, b: &mut Vec<i32>) -> i32 {
return abs(a[0] - b[0]) + abs(a[1] - b[1]);
}
fn abs(a: i32) -> i32 {
if a < 0 {
-a
} else {
a
}
}
// 正式方法
// KM算法
fn min_distance2(map: &mut Vec<Vec<i32>>) -> i32 {
let mut n = 0;
let mut m = 0;
for i in 0..map.len() as i32 {
for j in 0..map[0].len() as i32 {
n += get_max(0, map[i as usize][j as usize] - 1);
m += if map[i as usize][j as usize] == 0 {
1
} else {
0
};
}
}
if n != m || n == 0 {
return 0;
}
let mut nodes: Vec<Vec<i32>> = vec![];
for i in 0..n {
nodes.push(vec![]);
for _ in 0..2 {
nodes[i as usize].push(0);
}
}
let mut space: Vec<Vec<i32>> = vec![];
for i in 0..m {
space.push(vec![]);
for _ in 0..2 {
space[i as usize].push(0);
}
}
n = 0;
m = 0;
for i in 0..map.len() as i32 {
for j in 0..map[0].len() as i32 {
for _k in 2..=map[i as usize][j as usize] {
nodes[n as usize][0] = i;
nodes[n as usize][1] = j;
n += 1;
}
if map[i as usize][j as usize] == 0 {
space[m as usize][0] = i;
space[m as usize][1] = j;
m += 1;
}
}
}
let mut graph: Vec<Vec<i32>> = vec![];
for i in 0..n {
graph.push(vec![]);
for _ in 0..n {
graph[i as usize].push(0);
}
}
for i in 0..n {
for j in 0..n {
graph[i as usize][j as usize] =
-distance(&mut nodes[i as usize], &mut space[j as usize]);
}
}
return -km(&mut graph);
}
fn get_max<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T {
if a > b {
a
} else {
b
}
}
fn get_min<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T {
if a < b {
a
} else {
b
}
}
fn km(graph: &mut Vec<Vec<i32>>) -> i32 {
let nn = graph.len() as i32;
let mut match0: Vec<i32> = vec![];
let mut lx: Vec<i32> = vec![];
let mut ly: Vec<i32> = vec![];
// dfs過程中,碰過的點!
let mut x: Vec<bool> = vec![];
let mut y: Vec<bool> = vec![];
// 降低的預期!
// 公主上,打一個,降低預期的值,只維持最小!
let mut slack: Vec<i32> = vec![];
let mut falsev: Vec<bool> = vec![];
for _ in 0..nn {
match0.push(0);
lx.push(0);
ly.push(0);
x.push(false);
y.push(false);
slack.push(0);
falsev.push(false);
}
let invalid = 2147483647;
for i in 0..nn {
match0[i as usize] = -1;
lx[i as usize] = -invalid;
for j in 0..nn {
lx[i as usize] = get_max(lx[i as usize], graph[i as usize][j as usize]);
}
ly[i as usize] = 0;
}
for from in 0..nn {
for i in 0..nn {
slack[i as usize] = invalid;
}
x = falsev.clone();
y = falsev.clone();
// dfs() : from王子,能不能不降預期,匹配成功!
// 能:dfs返回true!
// 不能:dfs返回false!
while !dfs(
from,
&mut x,
&mut y,
&mut lx,
&mut ly,
&mut match0,
&mut slack,
graph,
) {
// 剛才的dfs,失敗了!
// 需要拿到,公主的slack裏面,預期下降幅度的最小值!
let mut d = invalid;
for i in 0..nn {
if !y[i as usize] && slack[i as usize] < d {
d = slack[i as usize];
}
}
// 按照最小預期來調整預期
for i in 0..nn {
if x[i as usize] {
lx[i as usize] = lx[i as usize] - d;
}
if y[i as usize] {
ly[i as usize] = ly[i as usize] + d;
}
}
x = falsev.clone();
y = falsev.clone();
// 然後回到while裏,再次嘗試
}
}
let mut ans = 0;
for i in 0..nn {
ans += lx[i as usize] + ly[i as usize];
}
return ans;
}
// from, 當前的王子
// x,王子碰沒碰過
// y, 公主碰沒碰過
// lx,所有王子的預期
// ly, 所有公主的預期
// match,所有公主,之前的分配,之前的爺們!
// slack,連過,但沒允許的公主,最小下降的幅度
// map,報價,所有王子對公主的報價
// 返回,from號王子,不降預期能不能配成!
fn dfs(
from: i32,
x: &mut Vec<bool>,
y: &mut Vec<bool>,
lx: &mut Vec<i32>,
ly: &mut Vec<i32>,
match0: &mut Vec<i32>,
slack: &mut Vec<i32>,
map: &mut Vec<Vec<i32>>,
) -> bool {
let nn = map.len() as i32;
x[from as usize] = true;
for to in 0..nn {
if !y[to as usize] {
// 只有沒dfs過的公主,才會去嘗試
let d = lx[from as usize] + ly[to as usize] - map[from as usize][to as usize];
if d != 0 {
// 如果當前的路不符合預期,更新公主的slack值
slack[to as usize] = get_min(slack[to as usize], d);
} else {
// 如果當前的路符合預期,嘗試直接拿下,或者搶奪讓之前的安排倒騰去
y[to as usize] = true;
if match0[to as usize] == -1
|| dfs(match0[to as usize], x, y, lx, ly, match0, slack, map)
{
match0[to as usize] = from;
return true;
}
}
}
}
return false;
}
// 為了測試
fn random_valid_matrix(len: i32) -> Vec<Vec<i32>> {
let mut graph: Vec<Vec<i32>> = vec![];
for i in 0..len {
graph.push(vec![]);
for _ in 0..len {
graph[i as usize].push(0);
}
}
let all = len * len;
for _i in 1..all {
graph[rand::thread_rng().gen_range(0, len) as usize]
[rand::thread_rng().gen_range(0, len) as usize] += 1;
}
return graph;
}
執行結果如下:

边栏推荐
- 景联文科技提供一站式智能家居数据采集标注解决方案
- Custom view subtotal
- 15、 IO stream (I)
- 10 Honest Facts I Want To Share With All Junior Developers
- Project analysis of Taishan crowdfunding mode: why is Taishan crowdfunding mode so popular?
- Ijkplayer compilation process record
- 景联文科技:数据标注行业现状及解决方案
- Comment utiliser le logiciel wangyou DFM pour l'analyse des plaques froides
- Jinglianwen technology provides voice data acquisition and labeling services
- Smart finance is upgraded again, and jinglianwen technology provides data collection and labeling services
猜你喜欢

MySQL系列之分库分表学习笔记

105. constructing binary trees from preorder and inorder traversal sequences
![[SketchUp 2021] CAD file import and modeling in the sketch master (establish elevation model in the sketch master by using CAD drawings), and the sketch master exports 2D, 3D and elevation effects of](/img/de/d0620a43c47a06d815c21ecb41a117.png)
[SketchUp 2021] CAD file import and modeling in the sketch master (establish elevation model in the sketch master by using CAD drawings), and the sketch master exports 2D, 3D and elevation effects of

Periodontitis investigation (ongoing)

105. 从前序与中序遍历序列构造二叉树

Pngquant batch bat and parameter description

Do you want to carry out rapid steel mesh design and ensure the quality of steel mesh? Look here

As the new trend of blind box e-commerce, how can the platform use blind box play to drain at low cost?

景联文科技:数据采集标注行业现状及解决方案

Why is the new e-commerce outlet mode so popular? What is the specific mode?
随机推荐
【sketchup 2021】草图大师中CAD文件的导入与建模(利用cad图纸在草图大师中建立立面模型)、草图大师导出成品为dwg格式的二维、三维、立面效果到cad中打开预览】
Wechat game execution wx Navigatetominiprogram jumps to other games and returns to the black screen
Jinglianwen Technology: current situation and solutions of data acquisition and labeling industry
【转】FPGA面试题
Unable to locate program input point getrawinputdevicelist in dynamic link library user32 DLL processing
AIO Introduction (VIII)
Construction and verification of Alibaba cloud server webrtc system
Tidb statistics
ML之FE:Vintage曲线/Vintage分析的简介、计算逻辑、案例应用之详细攻略
Byte (nine)
Ffmpeg compressed video.
景联文科技提供一站式智能家居数据采集标注解决方案
Detailed explanation of the player startup process of ijkplayer code walk through
Comprehensive overview of ijkplayer contour features for ijkplayer code walk through
If the key in redis data is in Chinese
景联文科技:数据采集标注行业现状及解决方案
时间格式化工具----moment.js(网页时间实时展示)
Excel data into database
That is, after the negative impact of gcat advertising e-commerce, is there no stable advertising e-commerce platform?
Notepad++ settings delete current line shortcut