第4章 例題4-1 古老的密碼(UVa1339)
阿新 • • 發佈:2018-12-26
題目:給定兩個長度相同且不超過100的字串,判斷是否能把其中一個字串的各個字母重排,然後對26個字母做一個一一對映,使得兩個字串相同。例如,JWPUDJSTVP重排後可以得到WJDUPSJPVT,然後把每個字母對映到它前一個字母(B->A, C->B, …, Z->Y, A->Z),得到VICTORIOUS。輸入兩個字串,輸出YES或者NO。
解析:既然字母可以重排,則每個字母的位置並不重要,重要的是每個字母出現的次數。這樣可以先統計出兩個字串中各個字母出現的次數,得到兩個陣列cnt1[26]和cnt2[26]。下一步需要一點想象力:只要兩個陣列排序之後的結果相同,輸入的兩個串就可以通過重排和一一對映變得相同。這樣,問題的核心就是排序。
#include<stdio.h> #include<string.h> #include<stdlib.h> #define maxn 100 int cmp( const void *a, const void *b){ return *(int *)a - *(int *)b; } int main() { char s1[maxn] = {0},s2[maxn] = {0}; int cnt1[26] = {0},cnt2[26] = {0}; int p = 0; scanf("%s%s",s1,s2); for(int i = 0; i < strlen(s1); i ++) cnt1[s1[i] - 'A'] ++; for(int i = 0; i < strlen(s2); i ++) cnt2[s2[i] - 'A'] ++; qsort(cnt1,26,sizeof(int),cmp); qsort(cnt2,26,sizeof(int),cmp); for(int i = 0; i < 26; i++){ if(cnt1[i] == cnt2[i]) p++; } if(p == 26) printf("YES"); else printf("NO"); }