[藍橋杯] 剪郵票問題

從網上看到的別人的代碼,稍微修改了一下,先看一下原博主怎麼寫的吧
**

原博主問題描述與代碼

**
下面的代碼 我只是加了一些註釋,少於了兩個把郵票塊數值轉換爲行列座標的數組,因爲水平不夠,那兩個數組的使用讓我理解起來很困難,所以我就去掉了

# include <iostream>
# include <cstring>
using namespace std;
int result = 0;
int mtx[10][10] = {0};  //保存郵票的圖   值0代表當前位置未被選中,值爲1代表當前位置被選中 
int c[5]={0};   // 記錄當前選擇的五個郵票塊的數字 
int sum(int x,int y)
{
    if(mtx[x][y] == 0)  //如果沒選擇就直接返回了  不用再判斷周圍的有沒有選中  因爲選中的必須要是相連的 
    {
        return 0;   
    }
    else
    {
        mtx[x][y] = 0;   //選過的就把值賦值爲0,避免無限循環 
        return 1+ sum(x-1,y) + sum(x+1,y) + sum(x,y-1) + sum(x,y+1);  //查找一下上下左右有沒有選中的,因爲這些位置的都是相連的 
    }

}
void dfs(int last,int i)  //選擇5個郵票塊的情況  這裏的5個郵票快都是遞增的 所以不存在重複的情況 
{
    if(i<5)   //這個if循環快可以是一個排列模板   
    {
        while(++last<=12)  //++last  首先視爲了配合主函數中的第一次傳入的值是0,0  讓第一次循環選中第一個郵票塊, 
        {                 //++也是爲了讓郵票塊的選擇都是遞增的,不會出現重複的情況, 
            c[i] = last;
            dfs(last,i+1);
        }
    }
    else  //已經選擇了5個 
    {

        memset(mtx,0,sizeof(mtx));//初始化 
        int x,y;
        //給mtx的對應位置複製
        for(int j =0;j<5;j++)
        {
              //根據選中的郵票塊數值  轉換爲對應的行列位置

            x = c[j]/4;  //x代表第幾行 
            y = c[j]%4-1;   //y代表第幾列  
            if(c[j]%4 == 0 )  
            {
                x = x-1;   
                y = 3; 
            } 
            mtx[x][y] = 1;          
        } 
        if(sum(x,y) == 5)  //都過座標方位mtx數組  判斷時否選擇了相鄰的5個郵票塊 
        {
            result ++;
        } 
    } 
}
int main()
{

    dfs(0,0); //從0,0開始 
    printf("%d\n",result);
    return 0;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章