1. 程式人生 > 其它 >CF1392E Omkar and Duck 題解

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;
}