洛谷 P1228 地毯填補問題(分治)
阿新 • • 發佈:2021-09-22
傳送門
解題思路
乍一看像是構造題。
我們從簡單開始想。
當有一個2*2的方格,很顯然可以直接鋪上。
於是我們發現,當一個矩形的1/4已經鋪好後,剩下的也可以鋪。
就像下圖一樣:(圖片來源:洛谷網校)
突破點:在已經鋪好的1/4的矩形正對著的位置鋪一個。
就像這樣:
所以可以分治處理,判斷已經填好的矩形在哪個位置。
AC程式碼
#include<cstdio> #include<iostream> #include<cstring> #include<iomanip> #include<cmath> #include<algorithm> using namespace std; int x,y,k; void divide(int lx,int ly,int rx,int ry,int x,int y){ if(lx==rx&&ly==ry){ return; } int midx=(lx+rx)/2,midy=(ry+ly)/2; if(x>=lx&&x<=midx&&y>=ly&&y<=midy){ cout<<midx+1<<" "<<midy+1<<" "<<1<<endl; divide(lx,ly,midx,midy,x,y); divide(lx,midy+1,midx,ry,midx,midy+1); divide(midx+1,ly,rx,midy,midx+1,midy); divide(midx+1,midy+1,rx,ry,midx+1,midy+1); return; } if(x>midx&&x<=rx&&y>=ly&&y<=midy){ cout<<midx<<" "<<midy+1<<" "<<3<<endl; divide(lx,ly,midx,midy,midx,midy); divide(lx,midy+1,midx,ry,midx,midy+1); divide(midx+1,ly,rx,midy,x,y); divide(midx+1,midy+1,rx,ry,midx+1,midy+1); return; } if(x>=lx&&x<=midx&&y>midy&&y<=ry){ cout<<midx+1<<" "<<midy<<" "<<2<<endl; divide(lx,ly,midx,midy,midx,midy); divide(lx,midy+1,midx,ry,x,y); divide(midx+1,ly,rx,midy,midx+1,midy); divide(midx+1,midy+1,rx,ry,midx+1,midy+1); return; } if(x>midx&&x<=rx&&y>midy&&y<=ry){ cout<<midx<<" "<<midy<<" "<<4<<endl; divide(lx,ly,midx,midy,midx,midy); divide(lx,midy+1,midx,ry,midx,midy+1); divide(midx+1,ly,rx,midy,midx+1,midy); divide(midx+1,midy+1,rx,ry,x,y); return; } } int main(){ ios::sync_with_stdio(false); cin>>k>>x>>y; divide(1,1,1<<k,1<<k,x,y); return 0; }