macro_rules! input { (source = $s:expr, $($r:tt)*) => { let mut iter = $s.split_whitespace(); input_inner!{iter, $($r)*} }; ($($r:tt)*) => { let 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::>() }; ($iter:expr, Chars) => { read_value!($iter, String).chars().collect::>() }; ($iter:expr, Usize1) => { read_value!($iter, usize) - 1 }; ($iter:expr, $t:ty) => { $iter.next().unwrap().parse::<$t>().expect("Parse error") }; } #[allow(unused)] #[inline] fn get_time()->f64{ static mut START:f64=-1.; let t=std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_secs_f64(); unsafe{ if START<0.{START=t;} t-START } } #[cfg(local)] #[allow(unused)] macro_rules! debug{ ()=>{ eprintln!(); }; ($x:literal)=>{ eprintln!("{:?}",$x); }; ($x:expr)=>{ eprintln!("{}: {:?}",stringify!($x),$x); }; ($x:literal,$($l:expr),*)=>{ eprint!("{:?}, ",$x); debug!($($l),*); }; ($x:expr,$($l:expr),*)=>{ eprint!("{}: {:?}, ",stringify!($x),$x); debug!($($l),*); } } #[cfg(not(local))] #[allow(unused)] macro_rules! debug{ ($($_:expr),*)=>{} } #[allow(unused)] mod rnd { static mut S:usize=88172645463325252; #[inline] pub fn next()->usize{ unsafe{ S^=S<<7; S^=S>>9; S } } #[inline] pub fn nextf()->f64{ unsafe{ std::mem::transmute::<_,f64>(0x3ff0000000000000|next()&0xfffffffffffff)-1. } } // [a,b) #[inline] pub fn range(a:usize,b:usize)->usize{ next()%(b-a)+a } #[inline] pub fn shuffle(list:&mut [T]){ for i in (0..list.len()).rev(){ list.swap(i,next()%(i+1)); } } #[inline] pub fn exu(a:usize,b:usize,skip:usize)->usize{ let ret=range(a,b-1); if ret==skip{b-1} else{ret} } } const N:usize=100; const M:usize=8; const A:usize=5; struct In{ pos:[(usize,usize);N] } impl In{ #[inline] fn input()->In{ input!{ n:usize, m:usize, tp:[(usize,usize);n] } assert_eq!((n,m),(N,M)); let mut it=tp.into_iter(); let mut pos=[(!0,!0);N]; pos.fill_with(||it.next().unwrap()); In{pos} } } struct Out{ route:[usize;N+1], dist:[[i64;N];N] } impl Out{ #[inline] fn new(input:&In)->Out{ let mut route=[!0;N+1]; let mut it=0..; route.fill_with(||it.next().unwrap()); route[N]=0; rnd::shuffle(&mut route[1..N]); let mut dist=[[-1;N];N]; const TA:usize=A.pow(2); for i in 0..N{ let (a,b)=input.pos[i]; for j in 0..N{ let (c,d)=input.pos[j]; dist[i][j]=(TA*((a-c)*(a-c)+(b-d)*(b-d))) as i64; } } Out{route,dist} } #[inline] fn score(&self)->i64{ let mut ret=0; for w in self.route.windows(2){ ret+=self.dist[w[0]][w[1]]; } ret } #[inline] fn try_opt2(&self,a:usize,b:usize)->i64{ // assert!(1<=a.min(b) && a.min(b)+1b{ std::mem::swap(&mut a,&mut b); } self.route[a..b].reverse(); } } fn sa(input:&In)->Out{ let mut cur=Out::new(input); let mut score=cur.score(); let mut best=score; let mut iter=0; let mut up=0; let mut th=[0;256]; loop{ if iter&1023==0{ const TL:f64=0.98; let p=get_time()/TL; if p>=1.{ break; } const T0:f64=1000000.; const T1:f64=0.; let heat=T0+(T1-T0)*p; th.fill_with(||(-heat*rnd::nextf().ln()) as i64); } iter+=1; let a=rnd::range(1,N); let mut b; while{ b=rnd::range(1,N); a-b+1<=2 }{} let diff=cur.try_opt2(a,b); if th[iter&255]>=diff{ score+=diff; cur.opt2(a,b); up+=1; best=best.min(score); } } let p=up as f64/iter as f64; debug!(iter,p); debug!(score,best); assert_eq!(score,cur.score()); cur } fn main(){ let input=In::input(); let out=sa(&input); // まずは何も作らない for _ in 0..M{ println!("0 0"); } println!("{}",out.route.len()); for &i in out.route.iter(){ println!("1 {}",i+1); } }