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

メモ

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

yukicoder No.55 正方形を描くだけの簡単なお仕事です。

問題はこちら
No.55 正方形を描くだけの簡単なお仕事です。 - yukicoder

もし正方形になり得る3点なら
その3点は直角二等辺三角形になっているはず
なので、「その点の周りが直角で、それをなす辺の長さが等しい」というような点が3つの中にあるかどうか探す

main(){
	int x[6],i,a,b,c,d,f=0;
	for(i=0;i<6;i++)scanf("%d",x+i);
	for(i=4;i>=0;i-=2){
	//(x[0],x[1])まわりが直角かどうかを調べる
		a=x[2]-*x;b=x[3]-x[1];
		c=x[4]-*x;d=x[5]-x[1];
		//辺の長さ
		if(a*c+b*d==0&a*a+b*b==c*c+d*d){f=1;break;}
		//内積が0(⇔直角)かつ辺の長さが等しいならフラグを立てて脱出
		*x^=x[i]^=*x^=x[i];
		x[1]^=x[i+1]^=x[1]^=x[i+1];
		//点の入れ替え(後述)
	}
	if(f)printf("%d %d",x[2]+x[4]-*x,x[3]+x[5]-x[1])
	//正方形が書けるなら座標の出力(後述)
	else printf("-1");
	//無理なら-1
	return 0;
}

点の入れ替えについて
常に(x[0],x[1])周りを調べることにしているので、全ての点について調べるには座標の方を入れ替える必要がある
最初に読み込んだ時を(a,b)(c,d)(e,f)とすると
1回目…(a,b)(c,d)(e,f)
2回目…(c,d)(a,b)(e,f)
3回目…(e,f)(a,b)(c,d)
と、ちゃんと全ての点について調べられている
座標の出力について
最後の1点を(p,q)とすると、完成する正方形の対角線の中心は
((x[2]+x[4])/2,(x[3]+x[5])/2)=((x[0]+p)/2,(x[1]+q)/2)
となるのでこれを解けば上の式が得られる

xorswapを2回も書くと長いよね…
ということで1回にした

x[6],i,a,b,c;
main(d){
	for(;~scanf("%d",x+i);i++);
	for(;i;){
		a=x[2]-*x;b=x[3]-x[1];
		c=x[4]-*x;d=x[5]-x[1];
		if(i%2==0&&a*c+b*d==0&&a*a+b*b==c*c+d*d)break;
		i--;
		//x[i%2]^=x[i]^=x[i%2]^=x[i];←yukicoderの環境だとバグる
		a=x[i%2];x[i%2]=x[i];x[i]=a;
	}
	i?printf("%d %d",x[2]+c,x[3]+d):puts("-1");
return 0;
}

2つのベクトル(a,b)と(c,d)が90度で交わり大きさが等しいことの判定はもっと簡単にできる
だって結局(c,d)は(-b,a)か(b,-a)になるしかない

x[6],i,a,b,c;
main(d){
	for(;~scanf("%d",x+i);i++);
	for(;a=x[2]-*x,b=x[3]-x[1],c=x[4]-*x,d=x[5]-x[1],i&&i--%2|(a+d|b-c&&a-d|b+c);x[i]^=x[i%2]^=x[i]^=x[i%2]);
	//今度はxorswapでもバグらない
	i=!printf(i?"%d %d":"-1",x[2]+c,x[3]+d);
}

代入文を押し込むことで

for(;~scanf("%d",x+i);i++);for(;a=x[2]-*x,b=x[3]-x[1],c=x[4]-*x,d=x[5]-x[1],i&&i--%2|(a+d|b-c&&a-d|b+c);x[i]^=x[i%2]^=x[i]^=x[i%2]);
//↑before ↓after
for(;~scanf("%d",x+i)?++i:i&&i--%2|((a=x[2]-*x)+(d=x[5]-x[1])|(b=x[3]-x[1])-(c=x[4]-*x)&&a-d|b+c)?x[i]^=x[i%2]^=x[i]^=x[i%2],1:0;);

とループ圧縮でき、最後の出力もループ内に押しこむことが出来て

x[6],i,a,b,c;main(d){
for(;a=~scanf("%d",x+i)?++i:i&&i--%2|((a=x[2]-*x)+(d=x[5]-x[1])|(b=x[3]-x[1])-(c=x[4]-*x)&&a-d|b+c)?x[i]^=x[i%2]^=x[i]^=x[i%2],1:!printf(i?"%d %d":"-1",x[2]+c,x[3]+d););
}

191B