ZJ19. 万万没想到之抓捕孔连顺
描述
输入描述
第一行包含空格分隔的两个数字 N和D(1 ≤ N ≤ 1000000; 1 ≤ D ≤ 1000000)输出描述
一个数字,表示不同埋伏方案的数量。结果可能溢出,请对 99997867 取模示例1
输入:
4 3 1 2 3 4
输出:
4
说明:
可选方案 (1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)示例2
输入:
5 19 1 10 20 30 50
输出:
1
说明:
可选方案 (1, 10, 20)示例3
输入:
2 100 1 102
输出:
0
说明:
无可选方案Rust 解法, 执行用时: 8ms, 内存消耗: 2436KB, 提交时间: 2022-05-16
use std::io::BufRead; pub struct Scanner<B> { reader: B, buf_str: Vec<u8>, buf_iter: std::str::SplitWhitespace<'static>, } impl<B: BufRead> Scanner<B> { pub fn new(reader: B) -> Self { Self { reader, buf_str: Vec::new(), buf_iter: "".split_whitespace(), } } pub fn token<T: std::str::FromStr>(&mut self) -> T { loop { if let Some(token) = self.buf_iter.next() { return token.parse().ok().expect("Failed parse"); } self.buf_str.clear(); self.reader .read_until(b'\n', &mut self.buf_str) .expect("Failed read"); self.buf_iter = unsafe { let slice = std::str::from_utf8_unchecked(&self.buf_str); std::mem::transmute(slice.split_whitespace()) } } } } fn main() { let stdin = std::io::stdin(); let mut scanner = Scanner::new(stdin.lock()); let n: usize = scanner.token(); let d: usize = scanner.token(); let mut r = 0; let mut v = vec![0; n]; for i in &mut v { *i = scanner.token() } while v.len() > 3 && v[1] - v[0] > d { v.pop(); } while v.len() > 3 && v[v.len()-1] - v[v.len()-2] > d { v.pop(); } if v.len() < 3 { println!("-1"); return } let mut left = 0; let mut right = 2; while right < v.len() { if v[right] - v[left] > d { left += 1 } else if right - left < 2 { right += 1 } else { let num = right - left; r += num * (num-1) / 2; right += 1 } } r = r % 99997867; println!("{}", r) }
C++ 解法, 执行用时: 10ms, 内存消耗: 1232KB, 提交时间: 2021-03-24
#include<cstdio> #include<cmath> #include<cstring> #include<iostream> #include<vector> #include<queue> #include<stack> #include<string> #include<algorithm> #include<map> #include<set> #define ll long long #define ull unsigned long long #define inf 0x3f3f3f3f #define P pair<ll,ll> const ll mod = 99997867; const ll maxn = 60000; using namespace std; inline int read() { char c = getchar(); int x = 0, f = 1; while(!isdigit(c)) {if(c == '-') f = -1; c = getchar();} while(isdigit(c)) {x = x*10 + c - '0'; c = getchar();} return f * x; } int main(){ int n = read(),d = read(); queue<int> path; ll ans = 0; for(int i = 0; i < n; i++) { if(path.empty()) {path.push(read());continue;} int input = read(); while(!path.empty() && path.front() + d < input) path.pop(); if(path.size() >= 2) ans += path.size() * (path.size()-1) / 2; path.push(input); ans %= mod; } printf("%lld",ans); }