1. 程式人生 > >PAT-B 1048. 數字加密(20)

PAT-B 1048. 數字加密(20)

題目連結在此

思路及AC程式碼

我們用字串陣列儲存兩個輸入,由於兩個字串的長度可能不相等,為了方便兩個字串的相同位進行運算,我們有兩種解決思路:

我的思路

記錄兩個字串的長度分別為lena,lenb,lena和lenb作比較,稍長的那個記作len_max,兩個長度差值的絕對值記作dis。

想將稍短的字串所有位都向後移動dis個位置,前面0~dis-1的位置補上’0’,這樣之後,兩個字串就對對齊了,直接實現題目中的演算法即可。

但是這種思路會遇到一個奇數位和偶數位的判定
這裡只稍做根本原因上的提示,至於判定方法,非常多樣,只需要能夠判定方法能夠做到奇偶交替,和題目中要求的奇偶性對上即可。

“坑”的提示:
由於從右往左的第一位為奇數位,當len_max=4時,從左往右的第一位為偶數位,len_max=5時,* 從左往右*的第一位為奇數位。

AC程式碼

#include<stdio.h>
#include<string.h>

char mp[] = {'0','1','2','3','4','5','6','7','8','9','J','Q','K'};

int main(){

    char a[101],b[101];

    scanf("%s %s",a,b);

    int lena = strlen(a);
    int
lenb = strlen(b); int len_max = (lena > lenb) ? lena : lenb; //先移動元素,使得a,b陣列元素對齊 if(lena < lenb){ int dis = lenb-lena; //a往後移動dis個位置 for(int i = lena-1; i >= 0; i--){ a[i+dis] = a[i]; } //給a陣列的0~dis-1賦值為'0' for(int i = 0; i < dis; i++){ a[i] = '0'
; } } else if(lena > lenb){ int dis = lena-lenb; for(int i = lenb-1; i >= 0; i--){ b[i+dis] = b[i]; } for(int i = 0; i < dis; i++){ b[i] = '0'; } }//else lena==lenb ,則可直接運算 //實現題目演算法 int res; int index = 0; for(int i = 0; i < len_max; i++){ //尤其注意奇偶性的判定 if((len_max-i+1)%2){ //對應於題目的偶數位情況 res = (b[i]-'0')-(a[i]-'0'); if(res<0){ res += 10; } printf("%c",mp[res]); } else{ //對應於題目的奇數位情況 res = ((a[i]-'0')+(b[i]-'0'))%13; printf("%c",mp[res]); } } return 0; }

《演算法筆記》思路

《演算法筆記》的思路在大體上和我的一致,兩者的區別也就差在如何對齊上。

《演算法筆記》中的對齊是將兩個字串都逆序儲存,在短的那個字串的後面補上dis個’0’,之後的演算法實現就和上面的一致了。

但是這種方法完美的避開了上面所提及的“”,因為這種方法奇偶性的判定完畢之後,直接和逆序之前的奇偶性是相反的(迴圈變數從左往右,從0開始,才有相反這個結論。如果從1開始,則奇偶性相同。主要還是和題目本身的奇偶性對應起來考慮即可。)。 比如:現在的從左往右第一位開始時i=0,i是偶數,而這一位本來應該是奇數位才對,因為這一位對應的是逆序前從右往左的左後一位。(似乎有點繞,需仔細思考)

這個演算法主要就是陣列逆序的實現,之後就和第一種思路的實現大同小異,暫時不貼程式碼了。