蓝桥杯真题 剪邮票 题解
2018-03-08 21:46
197 查看
题目:
如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。 (仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
正确答案在下面!!
(错误答案大神们请无视….)
Wrong Answer:
错因:这道题是不能边用dfs边判断,
比如图3的情况就不能考虑到:第2行第1列的格子可以选,
但是我写的代码里面就不能选,因为它的上面和左面的格子都没有被选过
而且!!我一开始的判断代码是错的,因为我判断了它左上角和右上角的格子,大概是判断代码写习惯了
搞了好几天才终于知道错误原因,( ! ^ ! )
思路:
用DFS;递归深度为格子数(3 * 4 = 12),每个格子有两种可能的选择:选or不选,递归出口为已选择的格子数为5;应该是选完5个格子后再判断是否满足上下左右相邻的条件,不能边选边判断;判断1个连通块包含的格子数用普通递归orDFS(这里我用的普通的递归)
PS:调试是个好东西!输出结果出错时在DFS里面多用下输出调试看看哪步出错
答案:116
Code:
如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。 (仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
正确答案在下面!!
(错误答案大神们请无视….)
Wrong Answer:
错因:这道题是不能边用dfs边判断,
比如图3的情况就不能考虑到:第2行第1列的格子可以选,
但是我写的代码里面就不能选,因为它的上面和左面的格子都没有被选过
而且!!我一开始的判断代码是错的,因为我判断了它左上角和右上角的格子,大概是判断代码写习惯了
搞了好几天才终于知道错误原因,( ! ^ ! )
//剪邮票 //wrong answer #include<bits/stdc++.h> using namespace std; int cnt = 0; bool selected[5][5]; int row,col,num;//num:要剪下来的个数 bool alright(int x, int y,int cur){ if(cur == 0) return true; int xx = x - 1,yy = y - 1; //上面 if(xx >= 1){ if(selected[xx][y]) return true; } //左面 if(yy >= 1){ if(selected[x][yy]) return true; } return false; /*wrong answer for(int dx = -1; dx <= 1; ++dx){ for(int dy = -1; dy <= 1; ++dy){ int xx = x + dx, yy = y + dy; if(xx < 1 || yy < 1 || xx > row || yy > col) continue; if(dx != 0 || dy != 0){ if(selected[xx][yy]) return true; } } } return false; */ } void dfs(int x, int y,int cur){ if(cur == num){ cnt++; return ; } if(cur < num && x > row) return ; //选 if(alright(x, y,cur)){ selected[x][y] = true; if( y == col) dfs(x + 1,1,cur + 1); else dfs(x, y + 1, cur + 1); selected[x][y] = false; } //不选 selected[x][y] = false; if(y == col) dfs(x + 1, 1, cur); else dfs(x, y + 1, cur); } int main(){ row = 3; col = 4; num = 5; for(int i = 1; i <= row; ++i){ for(int j = 1; j <= col; ++j){ selected[i][j] = false; } } dfs(1,1,0); cout<<cnt<<endl; return 0; }
思路:
用DFS;递归深度为格子数(3 * 4 = 12),每个格子有两种可能的选择:选or不选,递归出口为已选择的格子数为5;应该是选完5个格子后再判断是否满足上下左右相邻的条件,不能边选边判断;判断1个连通块包含的格子数用普通递归orDFS(这里我用的普通的递归)
PS:调试是个好东西!输出结果出错时在DFS里面多用下输出调试看看哪步出错
答案:116
Code:
//剪邮票 答案:116 #include<bits/stdc++.h> using namespace std; int cnt = 0; int selected[5][5]; int row,col,num;//num:要剪下来的个数 bool vis[5][5]; int unitcnt = 0; int move[4][2] = {{-1, 0}, {0, -1},{0, 1}, {1, 0}}; int getsum(int x, int y){ if(x < 1 || y < 1 || x > row || y > col) return 0; if(selected[x][y] == 0) return 0; if(vis[x][y]) return 0; vis[x][y] = true; return 1 + getsum(x - 1, y) + getsum(x, y - 1) + getsum(x + 1,y) + getsum(x, y + 1); } void dfs(int x, int y,int cur){ if(cur == num){ // cout<<"cur == num"<<endl; int i,j; bool flag = false; for(i = 1; i <= row; ++i){ for(j = 1; j <= col; ++j){ // cout<<"selected[] = "<<selected[i][j]<<endl; if(selected[i][j] == 1){ flag = true; break; } } if(flag) break; } for(int k = 1; k <= row; ++k){ for(int t = 1; t <= col; ++t){ vis[k][t] = false; } } // cout<<"selected[] = "<<selected[i][j]<<endl; if(getsum(i,j) == num) cnt++; return ; } if(cur < num && x > row) return ; //选 selected[x][y] = 1; if( y == col) dfs(x + 1,1,cur + 1); else dfs(x, y + 1, cur + 1); selected[x][y] = 0; //不选 selected[x][y] = 0; if(y == col) dfs(x + 1, 1, cur); else dfs(x, y + 1, cur); } int main(){ row = 3; col = 4; num = 5; for(int i = 1; i <= row; ++i){ for(int j = 1; j <= col; ++j){ selected[i][j] = 0; } } dfs(1,1,0); cout<<cnt<<endl; return 0; }
相关文章推荐
- 蓝桥杯 历届真题 剪邮票(枚举+判断连通性)
- 蓝桥杯第七届省赛JAVA真题----剪邮票
- 2013第四届蓝桥杯 C/C++本科A组 真题答案解析
- 匪夷所思的错误-16年蓝桥杯A组省赛的第七题-剪邮票
- 蓝桥杯 第三届C/C++预赛真题(10) 取球游戏(博弈)
- 蓝桥杯2014年以前JAVA历年真题及答案整理——闰年判断
- 蓝桥杯第六届国赛JAVA真题----密文搜索
- 蓝桥杯——真题训练之李白打酒
- 第五届蓝桥杯软件类省赛真题-Java高职-兰顿蚂蚁
- 剪邮票-蓝桥杯第七届javaA组--12元素选5元素不重复
- 第七届蓝桥杯javaB组真题解析-煤球数目(第一题)
- 2016年蓝桥杯第七届javaB组真题及答案
- 第五届蓝桥杯C++本科B组省赛真题详解
- 蓝桥杯——计算机研究生机试真题(2017.2.22)
- 2013年第四届蓝桥杯C/C++ C组决赛真题题解
- 2013蓝桥杯真题 —— 幸运数
- 蓝桥杯真题——第n个素数
- 算法笔记_213:第七届蓝桥杯软件类决赛部分真题(Java语言C组)
- 备战蓝桥杯(真题)第七届第九题“ 四平方和”
- 第七届蓝桥杯大赛个人赛省赛(软件类 C语言b组)真题 (个人解题思路)