方格分割 二進位制列舉+DFS(2017 第八屆藍橋杯省賽A組 第4題)
標題:方格分割
6x6的方格,沿著格子的邊線剪開成兩部分。
要求這兩部分的形狀完全相同。
如圖:p1.png, p2.png, p3.png 就是可行的分割法。
試計算:
包括這3種分法在內,一共有多少種不同的分割方法。
注意:旋轉對稱的屬於同一種分割法。
請提交該整數,不要填寫任何多餘的內容或說明文字。
由於影象是中心對稱,所以我們窮舉左邊的18個方格,共有2^18=262144種可能的情況,窮舉出左邊,通過對稱再得到右邊18個方格的情況,從而得到整附圖:
for(int i=0;i < (1<<18);++i) //i=0~2^18-1
{
for(int l=0;l<6;l++)
{
for(int c=0;c < 3;c++)
{
if(i&(1<<cnt)) //把i的每一位取出填入圖形
{
mp[l][c] = 1; //填充左半部分 1代表橘色 0代表黃色
mp[5-l][5-c] = 0; //對稱得到右半部分
}else
{
mp[l][c] = 0;
mp[5-l][5-c] = 1;
}
}
}
然後對填充後的圖形進行連通性檢測,如果填充後的圖形存在18個方塊的連通域則符合要求,方案數加一,用DFS檢測連通:
int vis[6][6];
int dx[8]={1, 0, 0,-1};
int dy[8]={0,-1, 1, 0};
int node_cnt;
int dfs(int x, int y)
{
for(int i=0;i < 4;i++) //從當前方格的上,下,左,右進行搜尋
{
int nx = x + dx[i];
int ny = y + dy[i];
if(node_cnt==18) return node_cnt; //已找到18個連通的方塊,則進行剪枝
if(0<=nx && nx < 6 && 0<=ny && ny <6)
{
if(mp[nx][ny]==mp[x][y]&&vis[nx][ny]==0) //找到同一區域方塊
{
vis[nx][ny]=1; //,標記
node_cnt++; //方塊數加1
dfs(nx,ny);
}
}
}
return node_cnt;
}
以下是完整程式碼:
#include <iostream>
#include <cstring>
using namespace std;
int mp[6][6];
int vis[6][6];
int dx[8]={1, 0, 0,-1};
int dy[8]={0,-1, 1, 0};
int node_cnt;
void printmp()
{
for(int i=0; i < 6;i++)
{
for(int j=0 ;j < 6;j++)
{
cout<<mp[i][j]<<" ";
}
cout<<endl;
}
}
int dfs(int x, int y)
{
for(int i=0;i < 4;i++)
{
int nx = x + dx[i];
int ny = y + dy[i];
if(node_cnt==18) return node_cnt;
if(0<=nx && nx < 6 && 0<=ny && ny <6)
{
if(mp[nx][ny]==mp[x][y]&&vis[nx][ny]==0)
{
vis[nx][ny]=1;
node_cnt++;
dfs(nx,ny);
}
}
}
return node_cnt;
}
int main()
{
int ans=0;
for(int i=0;i < (1<<18);++i)
{
int cnt=0;
for(int l=0;l<6;l++)
{
for(int c=0;c < 3;c++)
{
if(i&(1<<cnt))
{
mp[l][c] = 1;
mp[5-l][5-c] = 0;
}else
{
mp[l][c] = 0;
mp[5-l][5-c] = 1;
}
cnt++;
}
}
memset(vis,0,sizeof(vis));
node_cnt = 1;
vis[0][0] = 1;
if(dfs(0,0)==18) ans++;
// printmp();
// cin>>cnt;
}
cout<<ans/4; //中心對稱算一種,最後還要除以4
return 0;
}
最終答案為:509
相關文章
- 2017第八屆藍橋杯C/C++ B組省賽第二題 秒解C++
- 2017省賽藍橋杯B組
- 第九屆藍橋杯省賽C++A組 倍數問題(dfs)C++
- 藍橋杯__省賽__第八屆__C/C++__大學A組C++
- 第十三屆藍橋杯省賽A組
- 第14屆藍橋杯B組國賽
- 第十屆藍橋杯省賽C++B組 等差數列C++
- 第六屆藍橋杯省賽CC++B組C++
- 第十一屆藍橋杯省賽CC++組第二場比賽C++
- 2015年藍橋杯六屆省賽大學B組真題
- 2018藍橋杯省賽B組
- 藍橋杯第五屆省賽題目及題解
- 第九屆藍橋杯B組省賽———乘積最大
- 2017藍橋杯省賽第十題:k倍區間
- 題目 1841: [藍橋杯][2017年第八屆真題]發現環
- 藍橋杯__省賽__第七屆__C/C++__大學A組C++
- 藍橋杯__省賽__第九屆__C/C++__大學A組C++
- 第十三屆藍橋杯省賽C/C++ B組C++
- 2020藍橋杯省賽B組C++(第二場)真題C++
- 第十五屆藍橋杯軟體賽省賽C/C++B 組題解C++
- 第十五屆藍橋杯C++B組省賽總結C++
- 2013第四屆藍橋杯省賽C++A組【第一題:高斯日記】C++
- 第九屆藍橋杯軟體類省賽 Java B組 題目及解析Java
- 2018年第九屆藍橋杯省賽試題及詳解(Java本科A組)Java
- 藍橋杯省賽真題2013題解
- 2019年省賽第十屆藍橋杯B組C/C++試題H解 等差數列C++
- 【藍橋杯考前突擊】第十屆藍橋杯省賽C/C++大學B組 試題 D 數的分解C++
- 十進位制轉十六進位制(藍橋杯之前每日一題)每日一題
- 2016年藍橋杯C/C++組省賽第二題--生日蠟燭C++
- 2013年第四屆藍橋杯省賽試題及詳解(Java本科C組)Java
- 2014年第五屆藍橋杯省賽試題及詳解(Java本科C組)Java
- 第十四屆藍橋杯省賽C++ B組(個人經歷 + 題解)C++
- 2018年第九屆藍橋杯省賽試題及詳解(Java本科B組)Java
- 試題B:小球反彈(第十五屆藍橋杯省賽B組c/c++組)C++
- 歷屆藍橋杯省賽(C、C++)的答案(轉)C++
- 第十五屆藍橋杯大賽軟體賽省賽 C/C++ 大學 A 組C++
- 2018第九屆藍橋杯省賽C++B組【第四題:測試次數】C++
- 2013第四屆藍橋杯省賽C++B組【第六題:三部排序】C++排序