CF1392E Omkar and Duck 题解
一共会走 \(2n-2\) 步,那么钦定第 \(i\) 步向右 \(\Rightarrow\) 和的第 \(i\) 位为 \(1\),向下为 \(0\)。考虑如何构造出满足这个条件的矩阵:假设当前位置 \((i,j)\) 从右下到左上位于第 \(k\) 条斜线,那么这个位置为 \((j-1)(2^k-2^{k-1})\)。右下角 \((n,n)\) 特殊处理成 \(n-1\),一 check 发现这样就做完了!
点击查看代码
const int N=25+13;
int n;
ll two[N<<1],ans[N][N];
inline void init(){
two[0]=1;
for(int i=1;i<=(n<<1);++i) two[i]=two[i-1]*2;
}
inline void printt(int x,int y){print(x),print(' '),print(y),print('\n');flush();fflush(stdout);}
int main(){
//file();
scanf("%d",&n);
init();
for(int l=3;l<=(n<<1);++l){
for(int j=1;j<=n&&j<l;++j){
int i=l-j;if(i>n) continue;
ans[i][j]=(j-1)*two[(n<<1)-l]-(i==n&&j==n?0:(j-1)*two[(n<<1)-l-1]);
}
}
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j) print(ans[i][j]),print(' ');print('\n');
flush();fflush(stdout);
}
int q;scanf("%d",&q);
while(q--){
ll s;scanf("%lld",&s);
int x=1,y=1;
printt(x,y);
for(int i=(n<<1)-3;i>=0;--i){
if((s>>i)&1) ++y;
else ++x;
printt(x,y);
}
}
return 0;
}