CCF-訓練50題-NO.13-數碼管

一、問題描述

液晶數碼管用七筆阿拉數字表示的十個數字,把橫和豎的一 個短劃都稱爲一筆,即7有3筆,8有7筆等。對於十個數字一種排列,要做到兩相鄰數字都可以由另一個數字加上幾筆或減去幾筆組成,但不能又加又減。比如 7→3是允許的,7→2不允許。任意輸入一組數,判斷是否符合上述規則,注意,1在右邊。
這裏寫圖片描述

二、問題分析

可以聯想到我們離散數學課堂上學到的無相關係矩陣,7->3是允許的,則(7,3)(3,7)的值就是1,而7->2是不允許的,則(7,2)(2,7)的值就是0。以此類推寫出一個10*10的關係矩陣。這樣在判斷相鄰的數字的時候直接最爲座標進行比較就可以了。

三、算法分析

算法的核心是寫出10*10的矩陣
這裏寫圖片描述
錄入數字找到相應的座標,如果是1,則說明可以這麼變換,如果是0則說明不可以這樣的變換。返回相應的數字,這裏進行判斷,如果返回的是0則立刻輸出NO並且停止循環,如果是1,則返回數字進行累加,達到數組長度的,就是符合要求,輸出YES。同時也可以定義一個指標變量,當指標變量不是數組長度的時候就是NO

四、詳細設計(從算法到程序)

(一)定義關係矩陣

int st[10][10]={1,1,0,0,0,0,0,1,1,0,
            1,1,0,1,1,0,0,1,1,1,
            0,0,1,0,0,0,1,0,1,0,
            0,1,0,1,0,0,0,1,1,1,
            0,1,0,0,1,0,0,0,1,1,
            0,0,0,0,0,1,1,0,1,1,
            0,0,1,0,0,1,1,0,1,0,
            1,1,0,1,0,0,0,1,1,1,
            1,1,1,1,1,1,1,1,1,1,
            0,1,0,1,1,1,0,1,1,1};
int main(){
    string str[100];
    int point=0;
    while (1){
        int a[10];
        int p=0;
        cin>>a[0];

(二)輸入10個數,第一個數單獨輸入以便判斷錄入結束。

if (a[0]==-1) break;
        for (int j=1;j<10;j++) cin>>a[j];
        for (int i=0;i<9;i++){

(三)對輸入的數字組合進行改造,變成原數組的座標。比對數組裏面的元素是1還是0。

 if (st[a[i]][a[i+1]]==1) {
          p++;
          }
        }

(四)比對結果存入字符串數組

 if (p==9) str[point]="YES";
         else str[point]="NO";
        point++;
    }
    for (int k=0;k<point;k++) cout<<str[k]<<endl;
    return 0;
}

五、調試與測試

每次比較前後兩個數字的時候對應的座標應該是那兩個數各自都減1(數組下標是從0開始的)這樣處理不妨在錄入數組的時候就寄予相應的計算。最後還要注意循環的數量。是從第一個循環到倒數第二個。這樣子處理纔會方便。

六、分析與總結

這道題體現了轉換思維的重要性。如果沒有聯繫到離散當中的關係矩陣就要進行很多種情況額條件假設,而這些假設將會大大增加代碼的冗雜度,同時也大大降低了效率。於是這類有限結果,有限條件的題目,我們可以在main函數外面進行全部的條件假設,沒舉出所有的情況,這樣就可以更好更快的解題了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章