1. 程式人生 > >2016年第七屆藍橋杯C/C++程式設計本科B組省賽 剪郵票(結果填空)

2016年第七屆藍橋杯C/C++程式設計本科B組省賽 剪郵票(結果填空)

2016年第七屆藍橋杯C/C++程式設計本科B組省賽題目彙總:


剪郵票


如【圖1.jpg】, 有12張連在一起的12生肖的郵票。
現在你要從中剪下5張來,要求必須是連著的。
(僅僅連線一個角不算相連)
比如,【圖2.jpg】,【圖3.jpg】中,粉紅色所示部分就是合格的剪取。

請你計算,一共有多少種不同的剪取方法。


思路:先找到5個數的組合,然後從第一個數字開始遍歷,經過上下左右操作檢測5個數是否都被訪問一遍,如果5個數都可以遍歷到則種類+1。

在原圖中向上為-4,向下為+4,向左為-1,向右為+1,但是遇到3 4 5 7 8這種4+1=5但是這種情況不符合,所以重構一下原圖:

 

這樣,向上為-5,向下為+5,向左為-1,向右為+1,避免了每行最後一個+1後等於下一行第一個的情況。

答案:116

#include <iostream>
using namespace std;
int mp[12]= {1,2,3,4,6,7,8,9,11,12,13,14};
int aa[5],vis[5],sum=0;
int b[4]= {-1,1,-5,+5};
void dfs(int n)
{
    for(int i=0; i<4; i++)
    {
        int t=aa[n]+b[i];
        if(t<1||t>14||t==5||t==10) continue;
        for(int j=0; j<5; j++)
            if(!vis[j]&&aa[j]==t)
            {
                vis[j]=1;
                dfs(j);
            }
    }
}

int main()
{

    for(int a=0; a<12; a++)
        for(int b=a+1; b<12; b++)
            for(int c=b+1; c<12; c++)
                for(int d=c+1; d<12; d++)
                    for(int e=d+1; e<12; e++)
                    {
                        aa[0]=mp[a];
                        aa[1]=mp[b];
                        aa[2]=mp[c];
                        aa[3]=mp[d];
                        aa[4]=mp[e];
                        for(int i=0; i<5; i++)
                            vis[i]=0;
                        vis[0]=1;
                        dfs(0);
                        int flag=1;;
                        for(int i=0; i<5; i++)
                        {
                            if(vis[i]!=1)
                            {
                                flag=0;
                                break;
                            }
                        }
                        if(flag==0) continue;
                        else
                            sum++;
                    }

    cout<<sum<<endl;

    return 0;
}