排列組合算法


在此之前寫下最近的知識盲點:

全局變量沒初始化的情況下是0;而局部變量在沒有初始化的情況是以前遺留在內存中的垃圾數據。

------------------------------------------------------------------------------------------------------

同樣引用了大神YzlCoder的16年藍橋杯解答第六題

第六題:

方格填數

如下的10個格子

(如果顯示有問題,也可以參看【圖1.jpg】)

填入0~9的數字。要求:連續的兩個數字不能相鄰。
(左右、上下、對角都算相鄰)

一共有多少種可能的填數方案?

請填寫表示方案數目的整數。
注意:你提交的應該是一個整數,不要填寫任何多余的內容或說明性文字。



實現代碼:

    #include <stdio.h>  
    #include <math.h> 
	#include<stdbool.h> //使用bool型需要的庫 
    int flag[3][4]; //表示哪些可以填數  
    int mpt[3][4]; //填數  
    bool visit[10];  //在DEV C++中測試過C/C++中bool的默認值是0 
    int ans = 0;
    int run=0; 
    void init()   //初始化  
    {  
        int i,j;  
        for(i = 0 ; i < 3 ; i ++)  
            for(j = 0 ; j < 4 ; j ++)  
                flag[i][j] = 1;  
        flag[0][0] = 0;  
        flag[2][3] = 0;  
    }  
      
    void Solve()  
    {  
    	int i,j,k;
        int dir[8][2] = { 0,1,0,-1,1,0,-1,0,1,1,1,-1,-1,1,-1,-1};  
        int book = true;  
        for(i = 0 ; i < 3 ; i ++)  
        {  
            for(j = 0 ; j < 4; j ++)  
            {  
                //判斷每個數周圍是否滿足  
                if(flag[i][j] == 0)continue;  
                for(k = 0 ; k < 8 ; k ++)  
                {  
                    int x,y;  
                    x = i + dir[k][0];  //此處極其精彩,思想是將(i,j)作為坐標原點,
		    y = j + dir[k][1];	//而dir[8][2]每行(如(0,1),(0,-1))則標示
                                        //相對於(i,j)的偏移位置。
				        //一共有8行分別代表(i,j)的上下左右四個對角
                    if(x < 0 || x >= 3 || y < 0 || y >= 4 || flag[x][y] == 0) continue;  
                    if(abs(mpt[x][y] - mpt[i][j]) == 1)  book = false;  
                }  
            }  
        }  
        if(book) ans ++;  
    }  
      
    // 關鍵算法,組合算法。 
    void dfs(int index)  
    {  
        int i,x,y;  
        x = index / 4;  
        y = index % 4;  
        if( x == 3)          //x=3時index=12一次賦值完畢,接下來用Solve驗證
		             //時候滿足"連續的兩個數字不能相鄰"這個條件。 
        {  
            Solve();  
            return;  
        }  
        if(flag[x][y])  
        {  
            for(i = 0 ; i < 10 ; i ++)//雖然博主說過0-9不可以重復使用但是此處每個格子都賦值0-9,
				      //不過沒關系Solve()中又判斷if(abs(mpt[x][y] - mpt[i][j]) == 1) 
            {  
                if(!visit[i])  
                {   
                    visit[i] = true;  
                    mpt[x][y] = i;   
                    dfs(index+1);     //在for循環中嵌套遞歸!
                    visit[i] = false;  
                } 
            }  
        }  
        else  
        {  
            dfs(index+1);  
        }  
    }  
    int main()  
    {
        init();  
        dfs(0);  
        printf("%d\n",ans); 
        return 0;  
    }  

補充關於排列組合的一般性算法:

void combine(int pos,int h,const int n,const int r)
{
    int i;
    /*如果已選了r個元素了,則打印它們*/
    if (pos == r)
    {
        for(i=0; i<r; i++)
            cout<<s[p[i]];
        cout<<endl;
        return;
    }
    for(i=h; i<=n-r+pos; i++) /*對於所有未用的元素*/
    {
        if (!used[i])
        {
            /*把它放置在組合中*/
            p[pos] = i;
            /*使用該元素*/
            used[i] = 1;
            /*搜索第i+1個元素*/
            combine(pos+1,i+1,n,r);
            /*恢復遞歸前的值*/
            used[i] = 0;
        }
    }
}
Quotation: https://www.cnblogs.com/yangmingyu/p/6927741.html

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



排列組合算法 排列組合算法 排列組合算法 排列組合算法 排列組合算法 排列組合算法 排列組合算法 排列組合算法 排列組合算法 排列組合公式及排列組合算法
 
粤ICP备14056181号  © 2014-2021 ITdaan.com