kmjp's blog

競技プログラミング参加記です

yukicoder : No.1384 Bishop and Rook

未だにチェスの駒の名前と移動先の対応を覚えてない。
https://yukicoder.me/problems/no/1384

問題

H*Wのグリッドがある。
今任意のセルに駒を置いたとする。
その後、以下の手順を交互に繰り返す。

  • 駒を、点を共有する斜めのセルに移動する。
  • 駒を、辺を共有する隣接セルに移動する。

全セル1回ずつ通るような移動経路があるか判定せよ。

解法

グリッドサイズが縦横偶数か、1*1なら解あり。それ以外解なし。
あとはそれぞれの場合、グリッドの塗りつぶし方を愚直に考えよう。

int T,H,W;

void solve() {
	int i,j,k,l,r,x,y; string s;
	
	cin>>T;
	while(T--) {
		cin>>H>>W;
		if(H==1&&W==1) {
			cout<<0<<endl;
			cout<<"1 1"<<endl;
			continue;
		}
		if(H%2||W%2) {
			cout<<-1<<endl;
			continue;
		}
		cout<<H*W-1<<endl;
		if(H==2) {
			for(x=0;x<W;x+=2) {
				cout<<1<<" "<<x+1<<endl;
				cout<<2<<" "<<x+2<<endl;
				cout<<2<<" "<<x+1<<endl;
				cout<<1<<" "<<x+2<<endl;
			}
		}
		else if(W==2) {
			for(y=0;y<H;y+=2) {
				cout<<y+1<<" "<<1<<endl;
				cout<<y+2<<" "<<2<<endl;
				cout<<y+1<<" "<<2<<endl;
				cout<<y+2<<" "<<1<<endl;
			}
		}
		else {
			for(y=0;y<H;y+=2) {
				if(y%4==0) {
					// right
					cout<<y+1<<" "<<2<<endl;
					cout<<y+2<<" "<<1<<endl;
					cout<<y+1<<" "<<1<<endl;
					cout<<y+2<<" "<<2<<endl;
					for(x=2;x<W;x+=2) {
						cout<<y+2<<" "<<x+1<<endl;
						cout<<y+1<<" "<<x+2<<endl;
						cout<<y+1<<" "<<x+1<<endl;
						cout<<y+2<<" "<<x+2<<endl;
					}
				}
				else {
					for(x=W-2;x>=2;x-=2) {
						cout<<y+1<<" "<<x+2<<endl;
						cout<<y+2<<" "<<x+1<<endl;
						cout<<y+2<<" "<<x+2<<endl;
						cout<<y+1<<" "<<x+1<<endl;
					}
					cout<<y+1<<" "<<x+2<<endl;
					cout<<y+2<<" "<<x+1<<endl;
					cout<<y+1<<" "<<x+1<<endl;
					cout<<y+2<<" "<<x+2<<endl;
				}
			}
		}
		
		
	}
}

まとめ

こういうのダメな条件をさらっと出せないな…。