藍橋杯 - 數字排列(今有7對數字) - [兩種不同的DFS思路]


今有7對數字:兩個1,兩個2,兩個3,...兩個7,把它們排成一行。
要求,兩個1間有1個其它數字,兩個2間有2個其它數字,以此類推,兩個7之間有7個其它數字。如下就是一個符合要求的排列:

17126425374635

當然,如果把它倒過來,也是符合要求的。

請你找出另一種符合要求的排列法,並且這個排列法是以74開頭的。

注意:只填寫這個14位的整數,不能填寫任何多余的內容,比如說明注釋等。

 

答案:

74151643752362

 

解法1:

按照n=1~7進行DFS:我們每次嘗試在當前存在的若干空位中放入n,如果可以放入,就往下搜索n+1;

代碼:

#include<bits/stdc++.h>
using namespace std;
int num[15]={0,7,4,0,0,0,0,4,0,7,0,0,0,0,0};
void dfs(int n)
{
    if(n==4) dfs(n+1);
    if(n==7)
    {
        for(int i=1;i<=14;i++) printf("%d",num[i]); printf("\n");
        return;
    }

    for(int i=1;i<=14;i++)
    {
        if(i==1 || i==2 || i==7 || i==9) continue;
        int bak=i+n+1;
        if(bak>14) continue;

        if(num[i]==0 && num[bak]==0)
        {
            num[i]=num[bak]=n;
            dfs(n+1);
            num[i]=num[bak]=0;
        }
    }
}
int main()
{
    dfs(1);
}

 

解法2:

按照pos=1~14進行DFS:我們每次暴力枚舉要放入數字i = 1~7,如果 i 還未放入,就嘗試在當前的空位pos和pos+i+1中放入i,如果可以放入,就往下搜索pos+1;

代碼:

#include<bits/stdc++.h>
using namespace std;
int num[15]={0,7,4,0,0,0,0,4,0,7,0,0,0,0,0};
bool vis[8];
void dfs(int pos)
{
    if(num[pos]) dfs(pos+1);
    if(pos==15)
    {
        for(int i=1;i<=14;i++) printf("%d",num[i]); printf("\n");
        return;
    }

    for(int i=1;i<=7;i++)
    {
        if(vis[i]) continue;
        int bak=pos+i+1;
        if(bak>14) continue;
        if(num[pos]==0 && num[bak]==0)
        {
            num[pos]=num[bak]=i; vis[i]=1;
            dfs(pos+1);
            num[pos]=num[bak]=0; vis[i]=0;
        }
    }
}
int main()
{
    memset(vis,0,sizeof(vis));
    vis[4]=vis[7]=1;
    dfs(1);
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM