1. 程式人生 > >藍橋杯-方格分割-dfs

藍橋杯-方格分割-dfs

註意點 結果 out pos for bool oat 多少 bubuko

標題:方格分割

6x6的方格,沿著格子的邊線剪開成兩部分。

要求這兩部分的形狀完全相同。

如圖:p1.png, p2.png, p3.png 就是可行的分割法。

試計算:

包括這3種分法在內,一共有多少種不同的分割方法。

註意:旋轉對稱的 屬於同一種分割法。

請提交該整數,不要填寫任何多余的內容或說明文字。

技術分享圖片

技術分享圖片

技術分享圖片

阿西吧,這道題真的是,絕望,本來的思路是分別從左上角和右下角各引出一條線路,按走過的表格數進行計算,忘記了dfs是一頭撞到南墻不回頭不能有岔路的那種,於是乎按照格子來走是不行了,去網上找了找大神的思路,果然是大神,我咋著就沒有想到換個角度來看,不只是盯著表格,線呢!還有線呢!看線啊!還有人家是從中心開始的,中心是必經之路啊,無論怎樣中心都是對稱中心,真的是,最後,總結就是從中心兵分兩路,沿線直到抵達邊境,就算是一種結果,同樣還是用dfs但是換了一個角度了。跪。還有就是註意點在於題上已經提示了旋轉相同的只能算是一種結果,所以不要忘記除個4啊親!都是一樣的啊!委屈巴巴

#include<iostream>
using namespace std;
#define n 6
int board[n+1][n+1];
int cou =0;   //表示對稱圖形個數
struct coor{
    int i;
    int j;
};

coor direct1[4]= {{-1,0},{1,0},{0,-1},{0,1}},direct2[4] = {{1,0},{-1,0},{0,1},{0,-1}};
/*
答案509
思路:1、首先初始化棋盤未走過為0
      2、分析第一部分上下左右{(-1,0),(1,0),(0,-1),(0,1)}對稱於第二部分下上右左{(1,0),(-1,0),(0,1),(0,-1)}
      3、兩部分分別向四方進行試探,如果某方都沒有走過則可將下一步置1,然後繼續進行遞歸
*/ void init() { for(int i=0;i<=n;i++) //初始化棋盤 { for(int j=0;j<=n;j++) { board[i][j] = 0; } } board[3][3] = 1; } bool check(coor next1,coor next2) //檢查此位置是否可以走,如果可以返回true { if(board[next1.i][next1.j] == 0&&board[next2.i][next2.j] == 0
) { if(next1.i ==next2.i&&next1.j == next2.j){ return false; } return true; } return false; } void DFS(coor part1,coor part2) { if(part1.i == 0||part1.j == 0||part1.j == n||part1.i == n) { ++cou; return ; } coor next1,next2; for(int i=0;i<4;i++) { next1.i= part1.i+direct1[i].i; next1.j= part1.j+direct1[i].j; next2.i= part2.i+direct2[i].i; next2.j= part2.j+direct2[i].j; if(check(next1,next2)) { board[next1.i][next1.j] = board[next2.i][next2.j] = 1;//表示已經被走 DFS(next1,next2); board[next1.i][next1.j] = board[next2.i][next2.j] = 0; } } } int main() { coor start1,start2; start1.i = start1.j = 3; start2.i = start2.j = 3; init(); DFS(start1,start2); cout<<cou/4; return 0; }

藍橋杯-方格分割-dfs