読者です 読者をやめる 読者になる 読者になる

メモ

yukicoderで遊んでいる競プロゆるふわ勢

yukicoder No.61 リベリオン

問題はこちら
No.61 リベリオン - yukicoder

格子点を「通過」する判定はめんどくさいので、弾の速度をgcd(Vx,Vy)で割り、制限時間をその分伸ばすことにする
反射を考えるのは面倒なので、x軸y軸の各方向を2倍にしてループしていると考えるいつものやつ
格子点の数は2*W*2*H≦900なのでたかだか時刻900まで見ればあとはループする
愚直にシミュレーションすれば良い

w,h,mx,my,hx,hy,vx,vy,d,g,i;
gcd(p,q){return q?gcd(q,p%q):p;}
check(x,y){
	//弾の座標が(x,y)のとき、それが(mx,my)の4つの鏡像いずれかと一致しているかチェック
	x%=2*w;
	y%=2*h;
	return (x==mx)|(2*w-x==mx)&&(y==my)|(2*h-y==my);
}
main(){
	gets(&i);
	for(;~scanf("%d%d%d%d%d%d%d%d%d",&w,&h,&d,&mx,&my,&hx,&hy,&vx,&vy);){
		g=abs(gcd(vx,vy));
		for(i=0;i<999&&!check(abs(hx+vx/g*i),abs(hy+vy/g*i));i++);
		puts(i>d*g|i==999?"Miss":"Hit");
	}
}

変数を1文字にして、check関数をmainにまとめる
gcdの結果の代入を関数内で行う

w,h,p,q,r,s,t,u,v,i,x,y;
g(p,q){v=q?g(q,p%q):abs(p);}
main(d){
	for(gets(&w);v=~scanf("%d%d%d%d%d%d%d%d%d",&w,&h,&d,&p,&q,&r,&s,&t,&u);i=!puts(i>d*v|i>998?"Miss":"Hit"))
		for(g(t,u),w*=2,h*=2;x=abs(r+=t/v)%w,y=abs(s+=u/v)%h,++i<999&&(x-p&&w-x-p||y-q&&h-y-q););
}

scanfの%dが鬱陶しいのでmain再帰してみる

v,i,x,y,c;
g(p,q){v=q?g(q,p%q):abs(p);}
main(w,h,d,p,q,r,s,t,u){
	if(!~scanf("%d",&u))exit(0);
	if(c%9==!c++){
		for(g(t,u),w*=2,h*=2;x=abs(r+=t/v)%w,y=abs(s+=u/v)%h,++i<999&&(x-p&&w-x-p||y-q&&h-y-q););
		i=!puts(i>d*v|i>998?"Miss":"Hit");
	}
	main(h,d,p,q,r,s,t,u);
}

251B


2017/03/01追記
exit(0)しなくてもREにはならない

v,i,x,y,c;
g(p,q){v=q?g(q,p%q):abs(p);}
main(w,h,d,p,q,r,s,t,u){
	if(~scanf("%d",&u)){
		if(c%9==!c++){
			for(g(t,u),w*=2,h*=2;x=abs(r+=t/v)%w,y=abs(s+=u/v)%h,++i<999&&(x-p&&w-x-p||y-q&&h-y-q););
			i=!puts(i>d*v|i>998?"Miss":"Hit");
		}
		main(h,d,p,q,r,s,t,u);
	}
}

if文のカッコを外せないかなと睨むもRE、iへの代入のタイミングをはかってどうにか1B短縮

v,i,x,y,c;
g(p,q){v=q?g(q,p%q):abs(p);}
main(w,h,d,p,q,r,s,t,u){
	if(i=~scanf("%d",&u)){
		if(c%9==!c++)for(g(t,u),w*=2,h*=2;x=abs(r+=t/v)%w,y=abs(s+=u/v)%h,++i<999&&(x-p&&w-x-p||y-q&&h-y-q)||!puts(i>d*v|i>998?"Miss":"Hit"););
		main(h,d,p,q,r,s,t,u);
	}
}

243B