您的位置:首页 > 其它

蓝桥历届试题-剪邮票 dfs

2018-03-24 08:28 253 查看
剪邮票
如【图1.jpg】, 有12张连在一起的12生肖的邮票。

现在你要从中剪下5张来,要求必须是连着的。

(仅仅连接一个角不算相连)

比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
请填写表示方案数目的整数。

注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

116.

Code:

#include <bits/stdc++.h>
const int AX = 10;
using namespace std;

int dir[4][2] = {
{-1,0},
{0,1},
{1,0},
{0,-1}
};
int mark[AX][AX];
int vis[AX];
int num[AX];
int res ;
int c ;
void dfs( int k , int &c ){
int x = k / 4;
int y = k % 4;
//mark[x][y] = 1;
for( int i = 0 ; i < 4 ; i++ ){
int xx = x + dir[i][0];
int yy = y + dir[i][1];
if( xx < 0 || xx > 2 || yy < 0 || yy > 3 || mark[xx][yy] ) continue;
int tmp = xx * 4 + yy;
if( !vis[tmp]  ) continue;
c++;
mark[xx][yy] = 1;
dfs( tmp , c );
}
return;
}

void create( int st , int s , int tot ){

vis[s] = 1;
if( tot + 11 - s < 5 ) return;
if( tot == 5 ){
c = 1;
memset(mark,0,sizeof(mark));
mark[st/4][st%4] = 1;
dfs( st , c );
if( c == 5 ) res ++;
return;
}
for( int i = s + 1 ;  i < 12 ; i++ ){
if( !vis[i] ){
create( st , i , tot + 1 );
vis[i] = 0;
}
}
}

int main(){
res = 0;
for( int i = 0 ; i < 8 ; i ++ ){
memset( vis, 0 ,sizeof(vis));
create(i,i,1);
}
cout << res << endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: