1237: 剪邮票
时间限制: 1 Sec 内存限制: 128 MB题目描述
如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
请填写表示方案数目的整数。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
【图1.jpg】
【图2.jpg】
【图3.jpg】
输入
没有任何输入
输出
输出一个整数
用dfs从12个数中取5个(有序,最后要除以5!),然后用dfs搜索判断,最后ans除5的阶乘得到无序的
dfs搜索的时候不需要回退(不存在把自己绕死的情况),只需要从一个点出发,向四个方向搜索,能找到5个点就行了
#include<bits/stdc++.h> #define ll long long #define inf 0x3f3f3f3f using namespace std; int flag[13]={0}; int aa[10]; int ans=0; int dr[4]={1,-1,0,0}; int dl[4]={0,0,1,-1}; int mmp[4][5]; int mmfp[4][5]; int f; void ddfs(int x,int y) { for(int i=0;i<4;i++) { int tx=dr[i]+x; int ty=dl[i]+y; if(tx<=3&&tx>=1 && ty<=4&&ty>=1) { if(!mmfp[tx][ty] && mmp[tx][ty]) { f++; mmfp[tx][ty]=1; ddfs(tx,ty); } } } } int jude() { for(int i=1;i<=4;i++) mmp[1][i]=flag[i]; for(int i=5;i<=8;i++) mmp[2][i-4]=flag[i]; for(int i=9;i<=12;i++) mmp[3][i-8]=flag[i]; for(int i=1;i<=3;i++) { for(int j=1;j<=4;j++) { if(mmp[i][j]) { memset(mmfp,0,sizeof(mmfp)); f=1; mmfp[i][j]=1; ddfs(i,j); mmfp[i][j]=0; if(f==5) return 1; } } } return 0; } void dfs(int t) { if(t>5) { if(jude()) { ans++; } return; } for(int i=1;i<=12;i++) { if(!flag[i]) { flag[i]=1; aa[t]=i; dfs(t+1); flag[i]=0; } } } int main() { dfs(1); cout<<ans/(5*4*3*2)<<endl; return 0; }
哦,对了,答案116