cunzai_zsy0531

关注我

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;
}
posted @ 2022-05-28 15:08  cunzai_zsy0531  阅读(17)  评论(0编辑  收藏  举报