2015年第六屆藍橋杯C/C++程式設計本科B組決賽 密文搜尋(程式設計大題)
阿新 • • 發佈:2019-01-09
2015年第六屆藍橋杯C/C++程式設計本科B組決賽題目彙總:
密文搜尋
福爾摩斯從X星收到一份資料,全部是小寫字母組成。他的助手提供了另一份資料:許多長度為8的密碼列表。
福爾摩斯發現,這些密碼是被打亂後隱藏在先前那份資料中的。
請你編寫一個程式,從第一份資料中搜索可能隱藏密碼的位置。要考慮密碼的所有排列可能性。
資料格式:
輸入第一行:一個字串s,全部由小寫字母組成,長度小於1024*1024
緊接著一行是一個整數n,表示以下有n行密碼,1<=n<=1000
緊接著是n行字串,都是小寫字母組成,長度都為8
要求輸出:
一個整數, 表示每行密碼的所有排列在s中匹配次數的總和。
例如:
使用者輸入:
aaaabbbbaabbcccc
2
aaaabbbb
abcabccc
則程式應該輸出:
4
這是因為:第一個密碼匹配了3次,第二個密碼匹配了1次,一共4次。
資源約定:
峰值記憶體消耗 < 512M
CPU消耗 < 3000ms
請嚴格按要求輸出,不要畫蛇添足地列印類似:“請您輸入...” 的多餘內容。
所有程式碼放在同一個原始檔中,除錯通過後,拷貝提交該原始碼。
注意: main函式需要返回0
注意: 只使用ANSI C/ANSI C++ 標準,不要呼叫依賴於編譯環境或作業系統的特殊函式。
注意: 所有依賴的函式必須明確地在原始檔中 #include <xxx>, 不能通過工程設定而省略常用標頭檔案。
提交時,注意選擇所期望的編譯器型別。
思路:因為要求每行密碼的所有排列在s中匹配次數的總和,所以可以統計每行密碼中所包含的各個字母的個數,然後選取主串中的長度為8的區間,比較是否與密碼中包含的各個字母的個數相等。在選取主串中長度為8的區間時,實際上只有只有主串長度-7個長度為8的區間。
例如: 0 1 2 3 4 5 6 7 8 9 10 主串長度為11
則長度為8的區間只有0--7 1-- 8 2--9 3--10這4個,即11-4個。
#include <iostream> #include <stdio.h> #include <cstring> using namespace std; int main() { int n; char str[1005],s[10]; int a[1005][26],b[26]; memset(a,0,sizeof(a)); scanf("%s", str); for(int i=0; i<=(strlen(str)-8); i++) for(int j=i; j<=i+7; j++) a[i][str[j]-'a']+=1; scanf("%d",&n); int sum=0; for(int k=0; k<n; k++) { int flag; memset(b,0,sizeof(b)); scanf("%s", s); for(int i=0; i<strlen(s); i++) b[s[i]-'a']+=1; for(int i=0; i<=strlen(str)-8; i++) { flag=1; for(int j=0; j<26; j++) { if(a[i][j]!=b[j]) { flag=0; break; } } if(flag==1) sum++; } } cout<<sum<<endl; return 0; }