您的位置:首页 > 其它

蓝桥杯真题 剪邮票 题解

2018-03-08 21:46 197 查看
题目:

如【图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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: