これは普通に自力で解けた。
https://atcoder.jp/contests/codequeen2023-final-open/tasks/codequeen2023_final_d
問題
R*Cのチェス盤を考える。
クイーンの初期位置と、停止位置が与えられる。
クイーンの移動を3回で、初期位置から停止位置に移動するような移動法は何通りか。
解法
初期位置から1回移動したセルを列挙しておく。
停止位置から1回移動したセルを列挙し、そのぞれぞれにおいて、もう1回移動すると「初期位置から1回移動したセル」のうち何個に移動可能かを求めればよい。
int R,C,RS,CS,RT,CT; int Rs[101010]; int Cs[101010]; int RpCs[201010]; int RmCs[201010]; set<pair<int,int>> S; vector<pair<int,int>> cand(int r,int c) { int y,x; vector<pair<int,int>> cand; FOR(y,R) if(y!=r) cand.push_back({y,c}); FOR(x,C) if(x!=c) cand.push_back({r,x}); FOR(y,R) if(y!=r) { x=c+(y-r); if(x>=0&&x<C) cand.push_back({y,x}); x=c-(y-r); if(x>=0&&x<C) cand.push_back({y,x}); } return cand; } void solve() { int i,j,k,l,r,x,y; string s; cin>>R>>C>>RS>>CS>>RT>>CT; RS--,RT--,CS--,CT--; vector<pair<int,int>> A=cand(RS,CS); vector<pair<int,int>> B=cand(RT,CT); FORR2(y,x,A) { S.insert({y,x}); Rs[y]++; Cs[x]++; RpCs[y+x]++; RmCs[y-x+100000]++; } ll ret=0; FORR2(y,x,B) { if(S.count({y,x})) ret-=4; ret+=Rs[y]; ret+=Cs[x]; ret+=RpCs[y+x]; ret+=RmCs[y-x+100000]; } cout<<ret<<endl; }
まとめ
Queen縛りとはいえ、Bと似すぎててちょっと食傷気味。