日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2017西安交大ACM小学期 美妙音乐[差分KMP匹配]

發布時間:2023/12/3 编程问答 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2017西安交大ACM小学期 美妙音乐[差分KMP匹配] 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

美妙音樂

發布時間: 2017年7月3日 13:14?? 最后更新: 2017年7月5日 13:47?? 時間限制: 500ms?? 內存限制: 128M

描述

一段音樂是由若干個音符組成的,音樂中的某段音符稱為旋律。給定一首音樂,問某個旋律出現了多少次。注意:

(1)音樂中旋律是可以升調或降調的:例如 4 5 6和5 6 7是一個旋律;

(2)旋律不能重疊。

輸入

多組測試數據。
每組數據第一行有兩個正整數n,m
第二行有n個整數,表示這段音樂。
第三行有m個整數,表示一段旋律。
輸入數據滿足音樂和旋律中的音符均為1到88之間的整數,即對應鋼琴里的88種音調。
n,m不超過5×105
總輸入量n+m106

輸出

對于每組數據輸出一行一個整數,表示答案。

樣例輸入1?復制 14 3 1 1 5 5 6 6 5 4 4 3 3 2 2 1 2 2 1 樣例輸出1 3

題解:

對題目中給出的m個音符組成的的旋律做差分得到序列為(m-1)個相鄰差組成,記為模式

然后對整段音樂做差分,得到(n-1)個音符組成的序列,記為主串

對主串用模式進行KMP匹配,得到的匹配數目即是答案。

~!!!!!注意啦!題目中的旋律不能夠重疊,也就是說如果成功匹配到一個模式的時候,那么緊接著的下一個位置的差也不能用了,所以要i++;j = 0;

代碼:

#include <iostream> #include <cstdio> using namespace std; #define MAXN 2000001 int n,m; int a[MAXN]; int b[MAXN]; int s[MAXN]; int fail[MAXN]; void make_fail() {for (int i = 1, j = 0; i < m-1; i++){while (j && s[i] != s[j])j = fail[j - 1];if (s[i] == s[j])fail[i] = ++j;else fail[i] = 0;} } int search(int *str) {int ans = 0;for (int i = 0, j = 0; i < n-1; i++){while (j && str[i] != s[j])j = fail[j - 1];if (str[i] == s[j] && (++j == m-1)){ans++;i++;j = 0;}}return ans; } int main(){while(~scanf("%d%d",&n,&m)){for(int i = 0;i < n;i++){scanf("%d",&a[i]);}for(int i = 0;i < m;i++){scanf("%d",&b[i]);}if(m == 1){printf("%d\n",n);continue;}for(int i = 0;i < n-1;i++){a[i] = a[i+1] - a[i];}for(int i = 0;i < m-1;i++){s[i] = b[i+1] - b[i];}make_fail();int ans = search(a);printf("%d\n",ans);}return 0; }



總結

以上是生活随笔為你收集整理的2017西安交大ACM小学期 美妙音乐[差分KMP匹配]的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。