結果

問題 No.5020 Averaging
ユーザー nephrologist
提出日時 2024-02-25 17:35:08
言語 Rust
(1.83.0 + proconio)
結果
AC  
実行時間 277 ms / 1,000 ms
コード長 7,683 bytes
コンパイル時間 1,409 ms
コンパイル使用メモリ 191,340 KB
実行使用メモリ 25,492 KB
スコア 23,767,175
最終ジャッジ日時 2024-02-25 17:35:28
合計ジャッジ時間 15,328 ms
ジャッジサーバーID
(参考情報)
judge14 / judge10
純コード判定しない問題か言語
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 50
権限があれば一括ダウンロードができます
コンパイルメッセージ
warning: unnecessary parentheses around assigned value
   --> Main.rs:151:22
    |
151 |             nijou += (aa * aa + bb * bb);
    |                      ^                 ^
    |
    = note: `#[warn(unused_parens)]` on by default
help: remove these parentheses
    |
151 -             nijou += (aa * aa + bb * bb);
151 +             nijou += aa * aa + bb * bb;
    |

warning: 1 warning emitted

ソースコード

diff #
プレゼンテーションモードにする

#![allow(non_snake_case)]
#![allow(dead_code)]
#![allow(unused_imports)]
#![allow(unused_variables)]
#![allow(unused_mut)]
#![allow(non_upper_case_globals)]
//proconio
macro_rules! input {
(source = $s:expr, $($r:tt)*) => {
let mut iter = $s.split_whitespace();
input_inner!{iter, $($r)*}
};
($($r:tt)*) => {
let mut s = {
use std::io::Read;
let mut s = String::new();
std::io::stdin().read_to_string(&mut s).unwrap();
s
};
let mut iter = s.split_whitespace();
input_inner!{iter, $($r)*}
};
}
macro_rules! input_inner {
($iter:expr) => {};
($iter:expr, ) => {};
($iter:expr, $var:ident : $t:tt $($r:tt)*) => {
let $var = read_value!($iter, $t);
input_inner!{$iter $($r)*}
};
}
macro_rules! read_value {
($iter:expr, ( $($t:tt),* )) => {
( $(read_value!($iter, $t)),* )
};
($iter:expr, [ $t:tt ; $len:expr ]) => {
(0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
};
($iter:expr, chars) => {
read_value!($iter, String).chars().collect::<Vec<char>>()
};
($iter:expr, usize1) => {
read_value!($iter, usize) - 1
};
($iter:expr, $t:ty) => {
$iter.next().unwrap().parse::<$t>().expect("Parse error")
};
}
const mokuhyou: usize = 500000000000000000;
const n: usize = 45;
use std::cmp::Ordering;
use std::cmp::{Eq, Ord, PartialEq, PartialOrd};
use std::collections::BinaryHeap;
const WID: usize = 50;
const CHA: usize = 100;
const keta: usize = 100000000000000000;
pub fn get_time() -> f64 {
static mut STIME: f64 = -1.0; //
let t = std::time::SystemTime::now() // now
.duration_since(std::time::UNIX_EPOCH)
.unwrap();
// a.duration_since(b)a>b
let ms = t.as_secs() as f64 + t.subsec_nanos() as f64 * 1e-9;
// as_secs, .subsec_nanos()
unsafe {
if STIME < 0.0 {
STIME = ms; //
}
// get_time便
#[cfg(feature = "local")]
{
(ms - STIME) * 1.3
}
#[cfg(not(feature = "local"))]
{
ms - STIME
}
}
}
fn main() {
get_time();
input! {nn:usize, XY:[(usize,usize);n]}
let inp = Input { XY };
let mut rng = Xorshift::new(20250225);
// eprintln!("XY {:?}", &inp.XY);
let bestboard = beam_search(&inp, &mut rng, WID, CHA);
bestboard.printstate();
eprintln!(
"{}",
bestboard.nowval[0].0.abs_diff(mokuhyou) + bestboard.nowval[0].1.abs_diff(mokuhyou)
);
eprintln!("time {}", get_time());
eprintln!("cost {}", bestboard.cost);
}
struct Xorshift {
val: usize,
}
impl Xorshift {
fn new(seed: usize) -> Self {
let mut hoge = seed;
hoge ^= seed << 17;
hoge ^= seed >> 13;
hoge ^= seed << 5;
Xorshift { val: hoge }
}
fn next(&mut self) {
let hoge = self.val;
self.val ^= hoge << 17;
self.val ^= hoge >> 13;
self.val ^= hoge << 5;
}
fn rand(&mut self) -> f64 {
self.next();
(self.val / std::usize::MAX) as f64
}
fn randint(&mut self, a: usize, b: usize) -> usize {
self.next();
self.val % (b - a) + a
}
}
struct Input {
XY: Vec<(usize, usize)>,
}
#[derive(Clone)]
// #[derive(Debug, PartialEq, PartialOrd, Eq)]
struct Board {
orders: Vec<(usize, usize)>,
nowval: Vec<(usize, usize)>,
goukei: f64,
nijou: f64,
cost: f64,
}
impl Board {
fn new(inp: &Input) -> Self {
let mut goukei = 0.0;
let mut nijou = 0.0;
for &(a, b) in inp.XY.iter() {
let aa = a as f64 / keta as f64;
let bb = b as f64 / keta as f64;
goukei += aa + bb;
nijou += (aa * aa + bb * bb);
}
Self {
orders: vec![],
nowval: inp.XY.clone(),
goukei,
nijou,
cost: std::f64::MAX,
}
}
fn action(&mut self, a: usize, b: usize, rng: &mut Xorshift) {
// eprintln!("a b {} {}", a, b);
assert!(a != b);
let n1 = self.nowval[a].0;
let n2 = self.nowval[a].1;
let n3 = self.nowval[b].0;
let n4 = self.nowval[b].1;
let v1 = (n1 + n3) / 2;
let v2 = (n2 + n4) / 2;
self.nowval[a] = (v1, v2);
self.nowval[b] = (v1, v2);
self.orders.push((a + 1, b + 1));
let nn1 = n1 as f64 / keta as f64;
let nn2 = n2 as f64 / keta as f64;
let nn3 = n3 as f64 / keta as f64;
let nn4 = n4 as f64 / keta as f64;
let vv1 = (nn1 + nn3) / 2.0;
let vv2 = (nn2 + nn4) / 2.0;
self.nijou +=
2.0 * (vv1 * vv1 + vv2 * vv2) - (nn1 * nn1 + nn2 * nn2 + nn3 * nn3 + nn4 * nn4);
self.calccost(rng);
}
fn calccost(&mut self, rng: &mut Xorshift) {
let std = self.nijou / (n as f64 * n as f64)
- (self.goukei as f64 / n as f64) * (self.goukei as f64 / n as f64);
self.cost = (mokuhyou.abs_diff(self.nowval[0].0) + mokuhyou.abs_diff(self.nowval[0].1))
as f64
- 1.0 * std;
// self.cost = (mokuhyou.abs_diff(self.nowval[0].0) + mokuhyou.abs_diff(self.nowval[0].1))
// as f64
// + rng.rand();
}
fn printstate(&self) {
println!("{}", self.orders.len());
for &(a, b) in self.orders.iter() {
println!("{} {}", a, b);
}
}
}
//
impl Ord for Board {
fn cmp(&self, other: &Self) -> Ordering {
other.partial_cmp(self).unwrap_or(Ordering::Equal)
}
}
impl PartialEq for Board {
fn eq(&self, other: &Self) -> bool {
self.cost == other.cost
}
}
impl Eq for Board {} // OK
impl PartialOrd for Board {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
other.cost.partial_cmp(&self.cost)
}
}
fn beam_search(inp: &Input, rng: &mut Xorshift, beam_width: usize, challenge_time: usize) -> Board {
let mut board = Board::new(inp);
let mut preheap = BinaryHeap::new();
let mut nexheap = BinaryHeap::new();
board.calccost(rng);
let mut bestboard = board.clone();
preheap.push(board);
for turn in 0..50 {
eprintln!("turn {}", turn);
eprintln!("size {}", preheap.len());
for __ in 0..beam_width {
if preheap.is_empty() {
break;
}
// eprintln!("pre");
let mut preboard = preheap.pop().unwrap();
for ___ in 0..challenge_time {
let mut nexboard = preboard.clone();
let idx1 = rng.randint(0, n - 1);
let idx2 = rng.randint(idx1 + 1, n);
nexboard.action(idx1, idx2, rng);
nexheap.push(nexboard);
let mut nexboard = preboard.clone();
let idx1 = rng.randint(1, n);
nexboard.action(0, idx1, rng);
nexheap.push(nexboard);
}
}
preheap.clear();
for _ in 0..beam_width {
if nexheap.is_empty() {
break;
}
// eprintln!("nex");
let mut board = nexheap.pop().unwrap();
if board.cost < bestboard.cost {
eprintln!("best");
bestboard = board.clone();
}
preheap.push(board);
}
nexheap.clear()
}
bestboard
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0