結果
| 問題 |
No.5018 Let's Make a Best-seller Book
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2023-10-01 13:49:14 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 7,015 bytes |
| コンパイル時間 | 1,327 ms |
| コンパイル使用メモリ | 156,912 KB |
| 実行使用メモリ | 12,516 KB |
| スコア | 0 |
| 最終ジャッジ日時 | 2023-10-01 13:49:19 |
| 合計ジャッジ時間 | 4,843 ms |
|
ジャッジサーバーID (参考情報) |
judge13 / judge12 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | TLE * 1 -- * 99 |
コンパイルメッセージ
warning: associated function `weight` is never used
--> Main.rs:33:8
|
33 | fn weight(&self)->f64{
| ^^^^^^
|
= note: `#[warn(dead_code)]` on by default
warning: associated function `predict` is never used
--> Main.rs:38:8
|
38 | fn predict(&self,n:i64)->f64{
| ^^^^^^^
warning: associated function `write_ad` is never used
--> Main.rs:130:8
|
130 | fn write_ad(&mut self,level:i64){
| ^^^^^^^^
warning: 3 warnings emitted
ソースコード
#![allow(non_snake_case)]
fn main(){
get_time();
let mut IO=IO::new();
solve(&mut IO);
}
// softmaxで頑張るのが良さそうだが
// 係数がわかっているときに最適な戦略がわかるのか
// 最後は全力投入で良い
// 金をどれくらい残しておけばいいのか
fn solve(IO:&mut IO){
loop{
IO.write(&[0;N]);
IO.read();
}
}
#[derive(Clone,Copy,Default)]
struct Store{
P:i64, // 人気度
rest:i64, // 残り在庫数
D:f64, // 売れやすさの隠れパラメータ
}
impl Store{
fn weight(&self)->f64{
1.05f64.powi(self.P as i32)*self.D
}
// n冊入荷させたらどれくらい売れると予測されるのか
fn predict(&self,n:i64)->f64{
let ret=(n as f64).sqrt()*self.weight();
ret.min(n as f64)
}
}
const MONEY:i64=2000000;
const TURN:usize=52;
const N:usize=10;
struct IO{
scan:Scanner,
turn:usize,
money:i64,
store:[Store;N],
history:Vec<Vec<f64>>,
score:i64,
}
impl IO{
fn new()->IO{
let mut scan=Scanner::new();
input!{
scan,
d:(usize,usize,i64),
}
assert!(d==(TURN,N,MONEY));
let store=[Store{P:0,rest:0,D:1.};N];
let history=vec![vec![1.];N];
IO{
scan,
turn:0,
money:MONEY,
store,
history,
score:0,
}
}
fn read(&mut self){
input!{
self.scan,
money:i64,
s:[i64;N], // 売れたやつ
p:[i64;N], // 人気度
r:[i64;N], // 残り
}
let add=s.iter().sum::<i64>();
self.score+=add;
self.money+=add*1000;
for i in 0..N{
// historyを更新する
// min(n,n^0.5*1.05^P*D)=s[i]
// n^0.5*1.05^P*D=s[i]
// s[i]/(n^0.5)/(1.05^P)=D
let mut d=s[i] as f64/(self.store[i].rest as f64).sqrt()/1.05f64.powi(self.store[i].P as i32);
d=d.clamp(0.5,1.5);
self.history[i].push(d);
self.store[i].P=p[i];
assert!(self.store[i].rest==s[i]+r[i]);
self.store[i].rest=r[i];
self.store[i].D=self.history[i].iter().sum();
}
assert!(self.money==money);
self.turn+=1;
if self.turn==TURN{
self.dump();
std::process::exit(0);
}
}
fn write(&mut self,ans:&[usize]){
print!("1");
for i in 0..N{
let n=ans[i];
print!(" {}",n);
self.store[i].rest+=n as i64;
self.money-=n as i64*500;
}
assert!(0<=self.money);
}
fn write_ad(&mut self,level:i64){
print!("2 {}",level);
self.money-=500000*2i64.pow(level as u32-1);
for i in 0..N{
self.store[i].P+=level;
}
assert!(0<=self.money);
}
fn dump(&mut self){
eprintln!("score = {}",self.score);
}
}
#[allow(unused)]
fn get_time()->f64{
static mut START:f64=-1.;
let time=std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_secs_f64();
unsafe{
if START<0.{
START=time;
}
#[cfg(local)]{
(time-START)*1.6
}
#[cfg(not(local))]{
time-START
}
}
}
#[macro_export]
macro_rules! timer{
()=>{
#[cfg(local)]
let _timer=Timer(get_time());
}
}
static mut TIME:f64=0.;
struct Timer(f64);
impl Drop for Timer{
fn drop(&mut self){
unsafe{
TIME+=get_time()-self.0
}
}
}
#[allow(unused)]
mod rnd {
static mut N:usize=0xcafef00dd15ea5e5;
// 注意: 上の方のbitが0になってる
pub fn next()->usize{
unsafe{
let x=N;
N*=6364136223846793005;
(x^x>>22)>>(22+(x>>61))
}
}
pub fn hash()->u64{
unsafe{
let x=N;
N*=6364136223846793005;
x as u64
}
}
pub fn nextf()->f64{
unsafe{
std::mem::transmute::<u64,f64>(0x3ff0000000000000|(next() as u32 as u64)<<20)-1.
}
}
pub fn range(a:usize,b:usize)->usize{
assert!(a<b);
next()%(b-a)+a
}
pub fn range_skip(a:usize,b:usize,skip:usize)->usize{
assert!(a<=skip && skip<b);
let ret=range(a,b-1);
ret+(skip<=ret) as usize
}
pub fn rangei(a:i64,b:i64)->i64{
assert!(a<b);
(next()%((b-a) as usize)) as i64+a
}
pub fn shuffle<T>(list:&mut [T]){
for i in (0..list.len()).rev(){
list.swap(i,next()%(i+1));
}
}
}
trait RandomChoice{
type Output;
fn choice(&self)->&Self::Output;
}
impl<T> RandomChoice for [T]{
type Output=T;
fn choice(&self)->&T{
&self[rnd::next() as usize%self.len()]
}
}
struct Scanner{
stack:std::str::SplitAsciiWhitespace<'static>
}
impl Scanner{
fn new()->Self{
use std::io::Read;
let mut tmp=String::new();
std::io::stdin().read_to_string(&mut tmp).unwrap();
Self{stack:Box::leak(tmp.into_boxed_str()).split_ascii_whitespace()}
}
fn read<T:std::str::FromStr>(&mut self)->T{
self.stack.next().unwrap().parse::<T>().unwrap_or_else(|_|panic!("parse error {}",std::any::type_name::<T>()))
}
// インタラクティブ用
// fn new()->Self{
// Self{stack:"".split_ascii_whitespace()}
// }
// fn read<T:std::str::FromStr>(&mut self)->T{
// loop{
// if let Some(v)=self.stack.next(){
// return v.parse::<T>().unwrap_or_else(|_|panic!("{}: parse error",std::any::type_name::<T>()));
// }
// let mut tmp=String::new();
// std::io::stdin().read_line(&mut tmp).unwrap();
// assert!(!tmp.is_empty());
// self.stack=Box::leak(tmp.into_boxed_str()).split_ascii_whitespace();
// }
// }
}
#[macro_export]
macro_rules! input{
($scan:expr $(,)?)=>{};
($scan:expr, mut $name:ident:$t:tt $($rest:tt)*)=>{
let mut $name=read_value!($scan,$t);
input!{$scan $($rest)*}
};
($scan:expr, $name:ident:$t:tt $($rest:tt)*)=>{
let $name=read_value!($scan,$t);
input!{$scan $($rest)*}
};
}
#[macro_export]
macro_rules! read_value{
($scan:expr, ($($t:tt),*))=>{
($(read_value!($scan, $t)),*)
};
($scan:expr, [$t:tt;$len:expr])=>{
(0..$len).map(|_|read_value!($scan,$t)).collect::<Vec<_>>()
};
($scan:expr, [$t:tt])=>{
(0..$scan.read()).map(|_|read_value!($scan,$t)).collect::<Vec<_>>()
};
($scan:expr, Chars)=>{
read_value!($scan,String).chars().collect::<Vec<char>>()
};
($scan:expr, Usize1)=>{
read_value!($scan,usize)-1
};
($scan:expr, $t:ty)=>{
$scan.read::<$t>()
};
}