武漢做商城網(wǎng)站seo排名關(guān)鍵詞點(diǎn)擊
地毯填補(bǔ)問(wèn)題
題目描述
相傳在一個(gè)古老的阿拉伯國(guó)家里,有一座宮殿。宮殿里有個(gè)四四方方的格子迷宮,國(guó)王選擇駙馬的方法非常特殊,也非常簡(jiǎn)單:公主就站在其中一個(gè)方格子上,只要誰(shuí)能用地毯將除公主站立的地方外的所有地方蓋上,美麗漂亮聰慧的公主就是他的人了。公主這一個(gè)方格不能用地毯蓋住,毯子的形狀有所規(guī)定,只能有四種選擇(如圖):
并且每一方格只能用一層地毯,迷宮的大小為 2 k × 2 k 2^k\times 2^k 2k×2k 的方形。當(dāng)然,也不能讓公主無(wú)限制的在那兒等,對(duì)吧?由于你使用的是計(jì)算機(jī),所以實(shí)現(xiàn)時(shí)間為 1 1 1 秒。
輸入格式
輸入文件共 2 2 2 行。
第一行一個(gè)整數(shù) k k k,即給定被填補(bǔ)迷宮的大小為 2 k × 2 k 2^k\times 2^k 2k×2k( 0 < k ≤ 10 0\lt k\leq 10 0<k≤10);
第二行兩個(gè)整數(shù) x , y x,y x,y,即給出公主所在方格的坐標(biāo)( x x x 為行坐標(biāo), y y y 為列坐標(biāo)), x x x 和 y y y 之間有一個(gè)空格隔開。
輸出格式
將迷宮填補(bǔ)完整的方案:每一補(bǔ)(行)為 x y c x\ y\ c x?y?c( x , y x,y x,y 為毯子拐角的行坐標(biāo)和列坐標(biāo), c c c 為使用毯子的形狀,具體見(jiàn)上面的圖 1 1 1,毯子形狀分別用 1 , 2 , 3 , 4 1,2,3,4 1,2,3,4 表示, x , y , c x,y,c x,y,c 之間用一個(gè)空格隔開)。
樣例 #1
樣例輸入 #1
3
3 3
樣例輸出 #1
5 5 1
2 2 4
1 1 4
1 4 3
4 1 2
4 4 1
2 7 3
1 5 4
1 8 3
3 6 3
4 8 1
7 2 2
5 1 4
6 3 2
8 1 2
8 4 1
7 7 1
6 6 1
5 8 3
8 5 2
8 8 1
提示
spj 報(bào)錯(cuò)代碼解釋:
- c c c 越界;
- x , y x,y x,y 越界;
- ( x , y ) (x,y) (x,y) 位置已被覆蓋;
- ( x , y ) (x,y) (x,y) 位置從未被覆蓋。
upd?2023.8.19 \text{upd 2023.8.19} upd?2023.8.19:增加樣例解釋。
樣例解釋
大致思路
當(dāng)k=1時(shí),我們可以非常容易得到毯子填補(bǔ)的方案。當(dāng)k=2甚至更大時(shí),我們可以將其劃分為四大塊,但是公主位只有一個(gè),而對(duì)于其他沒(méi)有公主位的四方格,似乎和原問(wèn)題形式不一樣。但是我們可以對(duì)其加以處理,使其四個(gè)子問(wèn)題都具有相同形式——即,我們可以手動(dòng)為其他三個(gè)沒(méi)有公主位的四方格增加新的“公主位”。例如,當(dāng)公主位在左上角時(shí),我們可以將剩余三個(gè)四方格的交界處用毯子1來(lái)補(bǔ)上,這樣每個(gè)四方格都會(huì)被分配到一個(gè)公主位,稱為特殊的方陣,問(wèn)題便迎刃而解(如圖所示)。因此我們就可以采用分治的方法去不斷將正方形劃分為4個(gè)子正方形,再分別填充,直到小正方形邊長(zhǎng)為1時(shí),就是公主位了,不用做任何處理。
8x8的方格里,公主在右上角的格子里,然后在左上角的4x4方格中,選右下角,在左下角的方格中,選右上角,在右下角的方格中,選左上角,組成一個(gè)L,現(xiàn)在一個(gè)8x8的方格被分為四個(gè)4x4的方格,每個(gè)4x4的方格中,都有一塊被挖掉的部分,左上角的4*4方格中被挖掉的部分是它右下角組成L的那一塊,右上角的4x4方格中,挖去的是公主的位置,左下角和右下角的方格,挖去的都是L那部分
然后對(duì)每個(gè)4x4方格,重復(fù)以上操作,直到方格劃分為2*2的,四個(gè)格子中有一個(gè)被挖去,另外三個(gè)自然組成一個(gè)L
AC CODE
#include<bits/stdc++.h>
using namespace std;// 正方形左上角坐標(biāo)xx和yy,公主坐標(biāo)x和y,正方形邊長(zhǎng)k
void work(int xx,int yy,int x,int y,int k){if(k == 1) return;k/=2;// 左上角if(x < xx+k && y < yy+k){printf("%d %d %d\n",xx+k,yy+k,1);// 遞歸覆蓋左上角work(xx,yy,x,y,k);// 覆蓋右下角work(xx+k,yy+k,xx+k,yy+k,k);// 覆蓋左下角work(xx+k,yy,xx+k,yy+k-1,k);// 覆蓋右上角work(xx,yy+k,xx+k-1,yy+k,k);}// 右上角else if(x < xx+k && y >= yy+k){printf("%d %d %d\n",xx+k,yy+k-1,2);// 遞歸覆蓋左上角work(xx,yy,xx+k-1,yy+k-1,k);// 覆蓋右下角work(xx+k,yy+k,xx+k,yy+k,k);// 覆蓋左下角work(xx+k,yy,xx+k,yy+k-1,k);// 覆蓋右上角work(xx,yy+k,x,y,k);}// 左下角else if(x >= xx+k && y < yy+k){printf("%d %d %d\n",xx+k-1,yy+k,3);// 遞歸覆蓋左上角work(xx,yy,xx+k-1,yy+k-1,k);// 覆蓋右下角work(xx+k,yy+k,xx+k,yy+k,k);// 覆蓋左下角work(xx+k,yy,x,y,k);// 覆蓋右上角work(xx,yy+k,xx+k-1,yy+k,k);}// 右下角else{printf("%d %d %d\n",xx+k-1,yy+k-1,4);// 遞歸覆蓋左上角work(xx,yy,xx+k-1,yy+k-1,k);// 覆蓋右下角work(xx+k,yy+k,x,y,k);// 覆蓋左下角work(xx+k,yy,xx+k,yy+k-1,k);// 覆蓋右上角work(xx,yy+k,xx+k-1,yy+k,k);}
}int main()
{int x,y,k;cin >> k >> x >> y;work(1,1,x,y,(1 << k));return 0;
}