CF1392E Omkar and Duck 題解
阿新 • • 發佈:2022-05-28
一共會走 \(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; }