Pagini recente » Cod sursa (job #2561785) | Cod sursa (job #1757002) | Cod sursa (job #193761) | Cod sursa (job #2300517) | Cod sursa (job #2639833)
use std::fs::File;
use std::io::{Write, BufReader, BufWriter, BufRead};
// Suppose we have a function 'search' that returns false for all values until x and true for all other values
// Iterating through it will perform a binary search
// iter.last() will return a pair of i32 such that search(left) = false, search(right) = true and left + 1 == right
// The first 'left' and 'right' should be both be undefined values of the search domain
struct BinSearchIterator<T>
where T: Fn(i32) -> bool {
left: i32,
right: i32,
search: T,
}
impl<T> BinSearchIterator<T>
where T: Fn(i32) -> bool {
fn new(left: i32, right: i32, search: T) -> BinSearchIterator<T> {
BinSearchIterator {
left,
right,
search
}
}
}
impl<T> Iterator for BinSearchIterator<T>
where T: Fn(i32) -> bool{
type Item = (i32, i32);
fn next(&mut self) -> Option<Self::Item>{
if self.right - self.left > 1 {
let mid = (self.left + self.right) / 2;
if (self.search)(mid) {
self.right = mid;
} else {
self.left = mid;
}
Some((self.left, self.right))
} else if self.left < self.right {
let res = Some((self.left, self.right));
self.left = self.right;
res
} else {
None
}
}
}
fn main() {
let mut fin = BufReader::new(File::open("cautbin.in").unwrap());
let mut fout = BufWriter::new(File::create("cautbin.out").unwrap());
let mut line = String::new();
fin.read_line(&mut line).unwrap();
let n : usize = line.trim().parse().unwrap();
let mut line = String::new();
fin.read_line(&mut line).unwrap();
let v : Vec<i32> = line.trim()
.split(' ')
.map(|x| { x.parse().unwrap() } )
.collect();
assert_eq!(v.len(), n);
let mut line = String::new();
fin.read_line(&mut line).unwrap();
let m : usize = line.trim().parse().unwrap();
for _ in 0..m {
let mut line = String::new();
fin.read_line(&mut line).unwrap();
let arg : Vec<i32> = line.trim().split(' ').map(|x| {x.parse().unwrap() } ).collect();
assert_eq!(arg.len(), 2);
let optype = arg[0];
let x = arg[1];
match optype {
0 => {
let bs = BinSearchIterator::new(-1, n as i32, |t| -> bool { v[t as usize] > x });
let (left, _right) = bs.last().unwrap();
let res = if left == -1 || v[left as usize] != x { -1 } else { left + 1 };
fout.write(format!("{}\n", res).as_bytes()).unwrap();
}
1 => {
let res = BinSearchIterator::new(-1, n as i32, |t| -> bool { v[t as usize] > x }).last()
.unwrap().0 + 1;
fout.write(format!("{}\n", res).as_bytes()).unwrap();
}
2 => {
let res = BinSearchIterator::new(-1, n as i32, |t| -> bool { v[t as usize] >= x }).last()
.unwrap().1 + 1;
fout.write(format!("{}\n", res).as_bytes()).unwrap();
}
_ => {
}
}
}
fout.flush().unwrap();
}