• 蓝桥杯往届试题练习 剪邮票问题 (组合选取,判断是否联通)(类似枚举的思路)


    剪邮票


    如【图1.jpg】, 有12张连在一起的12生肖的邮票。
    现在你要从中剪下5张来,要求必须是连着的。
    (仅仅连接一个角不算相连)
    比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。


    请你计算,一共有多少种不同的剪取方法。


    请填写表示方案数目的整数。

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


    注意:这道题不可以简单地用深度优先搜索来解,否则算出的结果一定偏小。这是因为:

    深度搜索只能纵向往下搜索,那么如下图这种情况是无法搜索到的,因此,这道题目要求对实际问题的分析能力很高。

    从3->7->6  到了6该往哪走呢?走到5的话便无法回头走到10.同理走10的话就走不到5.




    因此,此题应该用枚举的思路来做。

    也就是从12个格子中选取出5个。判断它是否联通即可。

    关于从12个元素怎么从中选取5个,请看鄙人另一篇:

    https://blog.csdn.net/linruier2017/article/details/79726231


    程序源代码大致如下:



    #include<iostream>
    #include<set>
    #include<algorithm>
    using namespace std;
    int a[12];
    int dx[4]={-1,1,0,0};int dy[4]={0,0,-1,1};
    bool ok(int get[],int k)
    {
    for(int i=0;i<k;i++)if(get[i]>=get[k])return false;
    return true;
    }


    bool together(int n1,int n2)
    {
    int x1=n1/4;int y1=n1%4;
    int x2=n2/4;int y2=n2%4;
    for(int i=0;i<4;i++)
    {
    if(x1+dx[i]==x2&&y1+dy[i]==y2)return true;
    }
    return false;
    }
    bool liantong(int get[],int len)
    {
    int pos=0;
    set<int>s;s.insert(get[pos]);
    set<int>::iterator it;
    for(it=s.begin();it!=s.end();it++)
    {
    for(int i=1;i<len;i++)
    {
    if(together(*it,get[i])&&s.count(get[i])==0)
    {
    s.insert(get[i]);
    it=s.begin();
    }
    }
    }
    for(int i=0;i<len;i++)if(s.count(get[i])==0)return false;
    return true;
    }
    int main()
    {
    int sum=0;int total=0;
    //回溯法从12个格子里面选取5个出来
    int get5[5];
    for(int i=0;i<5;i++)get5[i]=-1;
    int k=0;int c[5];
    for(int i=0;i<5;i++)c[i]=0;
    while(k>=0)
    {
    while(c[k]<12)
    {
    get5[k]=c[k]++;
    if(ok(get5,k)&&k==4)
    {
    total++;
    if(liantong(get5,5))//判断选择的5张邮票是否联通 
    {
    sum++;
    }
    }
    else if(ok(get5,k)&&k<4)k++;
    }
    get5[k]==-1;
    c[k]=0;
    k--;

    cout<<"共有"<<total<<"种组合"<<endl;
    cout<<"符合要求的有"<<sum<<"种"<<endl;
    return 0;



    看到的大神如看到代码的不足或失误,敬请留言指出,不胜感激!

  • 相关阅读:
    http://rpm.pbone.net/
    Linux基础知识之 系统启动流程
    欧几里得算法及其扩展
    组合数相关
    poj2689 Prime Distance(思维+筛素数)
    一本通1624樱花(数学+唯一分解定理)
    CF33C Wonderful Randomized Sum(贪心+思维)
    HNOI 2008越狱(组合数学(乘法原理)+快速幂)
    唯一分解定理
    UVa 11827 Maximum GCD(gcd+读入技巧)
  • 原文地址:https://www.cnblogs.com/linruier/p/9485207.html
Copyright © 2020-2023  润新知