明日方舟三國殺第36
阿新 • • 發佈:2022-04-04
題目連結 https://www.luogu.com.cn/problem/P1228
這題一上來讓我很摸不著頭腦啊............
好不容易摸著了寫的時候又迷糊了........
好不容易寫完了結果傳引數傳不對........
好不容易傳對了提交7遍都WA了...........
找了半天bug發現沒加空格....................
分治+遞迴(遞的我屬實有點兒迷糊啊...)
題目說啦,只要你能用“地毯將除公主站立的地方外的所有地方蓋上”,你就能擁有到美麗漂亮聰慧的公主!
所以說,不管一共有幾種方法,只要用一種方式蓋上就好啦。
那麼面對210×210這麼大的宮殿,一定有某種規律讓我們能解決它。
ready?go!
當n=1時,無論公主在哪一個格子,我們都可以用一塊地毯蓋滿。
當n=2時,分解成四個n=1時的格子。
當n=3時,分解成四個n=2時的格子。
……(以此類推)
由此我們可以看出,這題得用遞迴。
可是當n=2時是可以分解成四個n=1時的格子啊,沒有公主我也沒辦法用一塊地毯蓋滿啊?
童話故事裡總會有假公主的出現。我們可以在中間的四個格子選擇三個,先鋪一塊地毯,每一個格子的地毯作為一個“假公主”,這樣不就使每個2×2的格子上有一位公主了嗎。
注意,在中間新增的地毯的缺口應指向公主。如下圖:
當n=3時:
以此類推,2k×2k的情況總能分解成4個2k-1×2k-1 的情況,直到k=2。
步驟大致為:找到真公主所在方位,在方格中間填補地毯(假公主),這時每個被分劃好的區域都有一個公主(真或假),開始遞迴。
放AC程式碼
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ul dfs(t,a,b,a+t-1,b+t-1)//向左上遞迴 4 #define ur dfs(t,a,b+t,a+t-1,b+t)//向右上遞迴 5 #define dl dfs(t,a+t,b,a+t,b+t-1)//向左下遞迴 6 #define dr dfs(t,a+t,b+t,a+t,b+t)//向右下遞迴 7 int n,x,y; 8 void dfs(int t,int a,int b,int x,int y) 9 //t表示此次要填的迷宮的大小 10 //a、b表示此迷宮左上角的位置 11 //x、y表示公主所在位置(或假公主的位置) 12 { 13 if(t==1) return; 14 t>>=1;//t/2,縮小迷宮範圍 15 if(x-a<t&&y-b<t)//缺口在左上角 16 { 17 cout<<a+t<<' '<<b+t<<' '<<1<<endl; 18 dfs(t,a,b,x,y); 19 ur; dl; dr; 20 } 21 if(x-a<t&&y-b>=t)//在右上角 22 { 23 cout<<a+t<<' '<<b+t-1<<' '<<2<<endl; 24 dfs(t,a,b+t,x,y); 25 ul; dl; dr; 26 } 27 if(x-a>=t&&y-b<t)//左下角 28 { 29 cout<<a+t-1<<' '<<b+t<<' '<<3<<endl; 30 dfs(t,a+t,b,x,y); 31 ul; ur; dr; 32 } 33 if(x-a>=t&&y-b>=t)//右下 34 { 35 cout<<a+t-1<<' '<<b+t-1<<' '<<4<<endl; 36 dfs(t,a+t,b+t,x,y); 37 ul; ur; dl; 38 } 39 } 40 int main() 41 { 42 cin>>n>>x>>y; 43 dfs(1<<n,1,1,x,y); 44 return 0; 45 }