题目描述

如下图, 有12张连在一起的12生肖的邮票。现在你要从中剪下5张来,要求必须是连着的。(仅仅连接一个角不算相连) 
 
比如,下面两张图中,粉红色所示部分就是合格的剪取。 
 
请你计算,一共有多少种不同的剪取方法。 

输出

请填写表示方案数目的整数。 
 
分析1
          使用开锁解锁机制、通过DFS一边搜索一边计数,每积累5个方格就停止进一步搜索,同时将结果存储起来。
   但是3、5、6、7、10(如图)此种情况是DFS做不到的,以下代码只用了DFS,只能得到82种结果。
 #include <iostream>
#include <vector>
#include <stdio.h>
#include <queue>
#include <cmath>
#include <algorithm>
using namespace std;
const int ROW = ;
const int COL = ;
int sum = ;
int num = ;
int dd[][] = {{,},{,},{,-},{-,}};
vector<vector<int> >a(ROW,vector<int>(COL,-));
vector<int>sig[];
vector<int>zz;
vector<int>temp;
void rightload(){
sig[sum] = temp;
}
bool checkrightload(){
temp = zz;
sort(temp.begin(),temp.end());
for(int i = ;i < sum;i++){
if(sig[i] == temp)
return false;
}
return true;
}
void lock(int i,int j){
num++;
a[i][j] = i*COL+j;
zz.push_back(a[i][j]);
}
void unlock(int i,int j){
num--;
a[i][j] = -;
zz.pop_back();
}
void dfs(int i,int j){
for(int zz = ;zz < ;zz++){
int ii = i + dd[zz][];
int jj = j + dd[zz][];
if(ii < ||jj < ||ii >= ROW||jj >= COL)
continue;
if(a[ii][jj] == -){
lock(ii,jj);
if(num == ){
if(checkrightload()){
rightload();
sum++;
}
}
else
dfs(ii,jj);
unlock(ii,jj);
}
}
}
int main(){
for(int i = ;i < ROW;i++){
for(int j = ;j < COL;j++){
lock(i,j);
dfs(i,j);
unlock(i,j);
}
}
for(int i = ;i < sum;i++){
for(int j = ;j < ;j++){
cout <<sig[i][j] <<" ";
}
cout <<endl;
}
cout << sum <<endl;
return ;
}

分析2

    为了弥补分析1所提出的漏洞,需要用BFS与DFS相结合,才能得到所有情况,以下是BFS与DFS结合解题的代码。

 #include <iostream>
#include <vector>
#include <stdio.h>
#include <queue>
#include <cmath>
#include <algorithm>
using namespace std;
const int ROW = ;
const int COL = ;
int sum = ;
int num = ;
int dd[][] = {{,},{,},{,-},{-,}};
vector<vector<int> >a(ROW,vector<int>(COL,-));
vector<int>sig[];
vector<int>zz;
vector<int>temp;
queue<pair<int,int> >myque;
void rightload(){
sig[sum] = temp;
}
bool checkrightload(){
temp = zz;
sort(temp.begin(),temp.end());
for(int i = ;i < sum;i++){
if(sig[i] == temp)
return false;
}
return true;
}
void lock(int i,int j){
num++;
a[i][j] = i*COL+j;
zz.push_back(a[i][j]);
}
void unlock(int i,int j){
num--;
a[i][j] = -;
zz.pop_back();
}
void bfs(int i,int j){
for(int zz = ;zz >= ;zz--){
int ii = i + dd[zz][];
int jj = j + dd[zz][];
if(ii < ||jj < ||ii >= ROW||jj >= COL)
continue;
if(a[ii][jj] == -){
myque.push({ii,jj});
}
}
while(!myque.empty()){
int ii = myque.front().first;
int jj = myque.front().second;
myque.pop();
lock(ii,jj);
if(num == ){
if(checkrightload()){
rightload();
sum++;
}
}
else{
bfs(ii,jj);
}
unlock(ii,jj);
}
}
void dfs(int i,int j){
for(int zz = ;zz < ;zz++){
int ii = i + dd[zz][];
int jj = j + dd[zz][];
if(ii < ||jj < ||ii >= ROW||jj >= COL)
continue;
if(a[ii][jj] == -){
lock(ii,jj);
if(num == ){
if(checkrightload()){
rightload();
sum++;
}
}
else{
dfs(ii,jj);
}
bfs(i,j);
unlock(ii,jj);
}
}
}
int main(){
for(int i = ;i < ROW;i++){
for(int j = ;j < COL;j++){
lock(i,j);
dfs(i,j);
unlock(i,j);
}
}
for(int i = ;i < sum;i++){
for(int j = ;j < ;j++){
cout <<sig[i][j] <<" ";
}
cout <<endl;
}
cout << sum <<endl;
return ;
}

最新文章

  1. CORS简介
  2. 在QtCreator中使用doxygen
  3. HDU 5742 Chess SG函数博弈
  4. 使用MicroService4Net 快速创建一个简单的微服务
  5. web api :Action Results in Web API 2
  6. Form表单提交数据的几种方式
  7. Lucene.net站内搜索—6、站内搜索第二版
  8. c#中的protected和internal
  9. UI进阶 多线程
  10. 译《Time, Clocks, and the Ordering of Events in a Distributed System》
  11. Kali学习笔记41:SQL手工注入(3)
  12. 容器中的诊断与分析3——live diagnosis——lldb
  13. 常用类-API文档-Integer
  14. AJAX方式发送远程请求报错:No &#39;Access-Control-Allow-Origin&#39; header
  15. 二进制样式的字符串与byte数组互转函数示例
  16. day08_python_1124
  17. hdu 4930 斗地主恶心模拟
  18. 使你的IT职业生涯更上一层楼de14条建议
  19. c++11 noexcept修饰符
  20. MySQL 实现将一个库表里面的数据实时更新到另一个库表里面

热门文章

  1. 前端学习笔记系列一:4 vue中@click.native
  2. 多元线性回归算法python实现(非常经典)
  3. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 辅助类:关闭图标
  4. CentOS7 部署 Jupyter Notebook
  5. python format使用方法
  6. 011.Oracle数据库分页,取前10条数据
  7. face_recognition人脸识别
  8. Day 27:Xpath技术
  9. 史无前例!一季度Facebook移除22亿假账号
  10. POJ 3983:快算24