蓝桥杯_剪邮票_暴力+广搜

来源:互联网 发布:js传值给jsp页面 编辑:程序博客网 时间:2024/06/08 11:40

剪邮票
如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
请填写表示方案数目的整数。

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

本题我写了两种解法

一:刚开始想用深度搜索,结果发现有以下4种情况用深搜是找不出来的。


加起来一共是34种,代码如下:

#include<stdio.h>#include<queue>#include<algorithm>using namespace std;struct Point{int x;int y;}pos,pt;int map[3][4],used[13][13][13][13][13],p[5],p1[5],book[3][4],res=0;int x[4]={-1,0,1,0},y[4]={0,1,0,-1};void dfs(Point pt,int n){int i,a,b;if(n==5){for(i=0;i<5;i++)p1[i]=p[i];sort(p1,p1+5);if(used[p1[0]][p1[1]][p1[2]][p1[3]][p1[4]])return;else{res++;used[p1[0]][p1[1]][p1[2]][p1[3]][p1[4]]=1;return;}}for(i=0;i<4;i++){a=pt.x+x[i];b=pt.y+y[i];if(a>=0&&a<3&&b>=0&&b<4&&book[a][b]!=1){Point p1;p1.x=a;p1.y=b;book[a][b]=1;p[n]=map[a][b];dfs(p1,n+1);book[a][b]=0;}}}void solve(){int i,j;for(i=0;i<3;i++)for(j=0;j<4;j++){Point pt;pt.x=i;pt.y=j;book[i][j]=1;p[0]=map[i][j];dfs(pt,1);book[i][j]=0;}}int main(){int i,j,k=0;for(i=0;i<3;i++) for(j=0;j<4;j++)map[i][j]=++k;solve();printf("%d\n",res+34);return 0;}

二:暴力加广搜,先找出从12个数字中挑出5中的可能,然后用广搜判断这五个点是否连通,如果连通就增加一次解法。


#include<stdio.h>#include<queue>#include<algorithm>using namespace std;struct Point{int x;int y;};int map[3][4],p[5],book[3][4],mark[3][4];int x[4]={-1,0,1,0},y[4]={0,1,0,-1};bool bfs(Point pt){int i,count=0,a,b;queue<Point>que;que.push(pt);                  while(!que.empty()){Point p1=que.front();que.pop();count++;for(i=0;i<4;i++){a=p1.x+x[i];b=p1.y+y[i];if(a>=0&&a<3&&b>=0&&b<4&&book[a][b]!=1&&mark[a][b]==1){Point p2;p2.x=a;p2.y=b;book[a][b]=1;que.push(p2);}}}if(count==5)return true;else return false;}bool solve(){int i,j,k=0;Point pt;memset(mark,0,sizeof(mark));memset(book,0,sizeof(book));for(i=0;i<3;i++)for(j=0;j<4;j++){if(map[i][j]==p[k]){mark[i][j]=1;k++;pt.x=i;pt.y=j;}}book[pt.x][pt.y]=1;if(bfs(pt))return true;return false;}int main(){int a,b,c,d,e,k=1,res=0;for(a=0;a<3;a++)for(b=0;b<4;b++)map[a][b]=k++;for(a=1;a<=8;a++){p[0]=a;for(b=a+1;b<=9;b++){p[1]=b;for(c=b+1;c<=10;c++){p[2]=c;for(d=c+1;d<=11;d++){p[3]=d;for(e=d+1;e<=12;e++){p[4]=e;if(solve())res++;}}}}}printf("%d\n",res);return 0;}


0 0
原创粉丝点击