use rand::Rng;use std::iter::repeat;fn main() { let mut a = vec![71, 29, 13, 74, 90, 8, 30, 25]; let mut b = vec![72, 1, 50, 98, 86, 86, 52, 57]; let mut c = vec![11, 24, 61, 70, 11, 90, 13, 30]; let ans = ways2(&mut a, &mut b, &mut c); println!("ans = {}", ans); let nn: i32 = 100; let vv: i32 = 100; let test_time: i32 = 5000; println!("测试开始"); for i in 0..test_time { let n = rand::thread_rng().gen_range(0, nn) + 1; let mut a = random_array(n, vv); let mut b = random_array(n, vv); let mut c = random_array(n, vv); let ans1 = ways1(&mut a, &mut b, &mut c); let ans2 = ways2(&mut a, &mut b, &mut c); if ans1 != ans2 { println!("出错了!{}", i); println!("ans1 = {}", ans1); println!("ans2 = {}", ans2); break; } } println!("测试结束");}
// 暴力方法// 时间复杂度O(N^3)// 为了验证fn ways1(a: &mut Vec<i32>, b: &mut Vec<i32>, c: &mut Vec<i32>) -> i32 { let n = a.len() as i32; a.sort(); b.sort(); c.sort(); let mut ans = 0; for i in 0..n { let mut j = 0; while j < n && b[j as usize] <= a[i as usize] * 2 { if b[j as usize] > a[i as usize] { let mut k = 0; while k < n && c[k as usize] <= b[j as usize] * 2 { if c[k as usize] > b[j as usize] { ans += 1; } k += 1; } } j += 1; } } return ans;}
// 正式方法// 时间复杂度O(N * logN)fn ways2(a: &mut Vec<i32>, b: &mut Vec<i32>, c: &mut Vec<i32>) -> i32 { let n = a.len() as i32; a.sort(); b.sort(); c.sort(); // B里面的记录 let mut help: Vec<i32> = repeat(0).take(n as usize).collect(); let mut i = 0; let mut l = -1; let mut r = 0; while i < n { while l + 1 < n && c[(l + 1) as usize] <= b[i as usize] { l += 1; } while r < n && c[r as usize] <= b[i as usize] * 2 { r += 1; } help[i as usize] = get_max(r - l - 1, 0); i += 1; } for i in 1..n { help[i as usize] += help[(i - 1) as usize]; } let mut ans = 0; let mut i = 0; let mut l = -1; let mut r = 0; while i < n { while l + 1 < n && b[(l + 1) as usize] <= a[i as usize] { l += 1; } while r < n && b[r as usize] <= a[i as usize] * 2 { r += 1; } if r - l - 1 > 0 { ans += sum(&mut help, l + 1, r - 1); } i += 1; } return ans;}
fn sum(help: &mut Vec<i32>, l: i32, r: i32) -> i32 { return if l == 0 { help[r as usize] } else { help[r as usize] - help[(l - 1) as usize] };}
fn get_max<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T { if a > b { a } else { b }}
// 为了测试fn random_array(n: i32, v: i32) -> Vec<i32> { let mut arr: Vec<i32> = vec![]; for _i in 0..n { arr.push(rand::thread_rng().gen_range(0, v)); } return arr;}
评论