1. 程式人生 > 其它 >藍橋杯每日一題1.6 2017省賽A組4.方格分割[DFS]

藍橋杯每日一題1.6 2017省賽A組4.方格分割[DFS]

技術標籤:DFS藍橋杯dfs

題目描述

6x6的方格,沿著格子的邊線剪開成兩部分。要求這兩部分的形狀完全相同。如圖就是可行的分割法。

試計算:包括這3種分法在內,一共有多少種不同的分割方法。注意:旋轉對稱的屬於同一種分割法。

輸出

輸出一個整數表示答案

https://blog.csdn.net/weixin_43914593/article/details/112257103

✬✬✬✬✬如何從分割方格來聯想到DFS呢?✬✬✬✬✬

highlight:

1.由於旋轉對稱的屬於同一種分割法,得到的結果要/4

2.由題意,這一條切割線必定經過圖的中心點,那麼我們一旦確定了半條到達邊界的分割線,就能根據這半條對稱畫出另外半條。(所以就可以從中心的點往外搜)

3.在搜尋過程中需要注意的是,我們搜尋出的半條分割線不能同時經過關於中心對稱的兩個點,所以在標記時,需要將對稱的點也標上。(vis[x][y]=true的同時vis[6-x][6-y]=true)

4.向右、向左、向上、向下,四個方向DFS即可。

int X[]={0,-1,1,0,0};

int Y[]={0,0,0,-1,1};

x+=X[i];

y+=Y[i];

mistakes:

1.在for迴圈裡面進行遞迴

2.走完一步之後再來詢問是否訪問過這個點

for(int i = 1 ; i <= 4 ; i++){ //上下左右四個方向

x += X[i]; y += Y[i]; //走一步

if(!vis[x][y]){ // 若該點未訪問則繼續深搜

vis[x][y] = true; // 當前的點標註為已訪問

vis[6 - x][6 - y] = true;

dfs(x, y); // 繼續深搜

vis[6 - x][6 - y] = false;

vis[x][y] = false;

}

x -= X[i]; y -= Y[i];

}

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<set>
#include<queue>
#include<stack>
#include<map>
using namespace std;
typedef long long ll;
const int maxn = 110000;

int X[]={0,-1,1,0,0};
int Y[]={0,0,0,-1,1};

bool vis[10][10];
int ans=0;

void dfs(int x,int y)
{
    if(x==0||x==6||y==0||y==6)
    {
        ans++;
        return ;
    }
    for(int i=1;i<=4;i++)
    {
        x+=X[i];
        y+=Y[i];
        if(!vis[x][y])
        {
            vis[x][y]=true;
            vis[6-x][6-y]=true;
            dfs(x,y);
            vis[6-x][6-y]=false;
            vis[x][y]=false;
        }
        x-=X[i];
        y-=Y[i];
    }
}

int main()
{
    vis[3][3]=true;
    dfs(3,3);
    cout<<ans/4;
    return 0;
}