每个测试文件均包含多组测试数据。第一行输入一个整数
代表数据组数,每组测试数据描述如下:
第一行输入一个整数
代表棍子的种类。
此后
行,第
行输入两个整数
代表第
种棍子的长度和数量。
除此之外,保证单个测试文件的
之和不超过
。
在一行上输出一个实数,代表组成的最大等腰三角形的面积。如果无法组成等腰三角形,则直接输出
。
由于实数的计算存在误差,当误差的量级不超过
时,您的答案都将被接受。具体来说,设您的答案为
,标准答案为
,当且仅当
时,您的答案将被接受。
2 3 3 3 2 1 3 1 2 1 2 12 1
3.89711431702997391060 -1
对于第一组测试数据,可以构造
为底、
为腰的三角形,面积
;也可以构造
为底、
为腰的三角形,面积
。显然,后者更大。
本题数据量较大,我们建议您使用较快的读入方式。
use std::collections::HashMap; use std::io::*; fn solve(group: HashMap<usize, usize>) { let congruent_group: HashMap<usize, usize> = group .iter() .filter(|(_, &v)| v >= 2) .map(|(k, v)| (*k, *v)) .collect(); if congruent_group.is_empty() { println!("-1"); return; } let mut max_area = 0.0f64; let mut found = false; for base_side in group.iter() { let (&length_b, _) = base_side; for congruent_side in congruent_group.iter() { let (&length_c, &count_c) = congruent_side; if 2 * length_c <= length_b { continue; } if length_b != length_c && count_c < 2 { continue; } if length_b == length_c && count_c < 3 { continue; } found = true; let area = (length_b as f64) * (length_c.pow(2) as f64 - length_b.pow(2) as f64 / 4.0).sqrt() / 2.0; max_area = max_area.max(area); } } if found { println!("{}", max_area); } else { println!("-1"); } } fn main() { let stdin = stdin(); let mut line = String::new(); stdin.read_line(&mut line).unwrap(); line.pop(); let t: usize = line.parse().unwrap(); for _ in 0..t { line.clear(); stdin.read_line(&mut line).unwrap(); line.pop(); let n: usize = line.parse().unwrap(); let lines: Vec<(usize, usize)> = stdin .lock() .lines() .take(n) .map(|l| { let l = l.unwrap(); let mut it = l.split_whitespace(); ( it.next().unwrap().parse().unwrap(), it.next().unwrap().parse().unwrap(), ) }) .collect(); let group = lines.iter().fold(HashMap::new(), |mut acc, &(a, b)| { acc.entry(a).and_modify(|x| *x += b).or_insert(b); acc }); solve(group); } }