POJ 1743 Musical Theme
2014-02-16 09:25
239 查看
Description
A musical melodyis represented as a sequence of N (1<=N<=20000)notes that are integers inthe range 1..88, each representing a key on the piano. It is unfortunate buttrue that this representation of melodies ignores
the notion of musical timing;but, this programming task is about notes and not timings.
Many composers structure their music around a repeating&qout;theme&qout;, which, being a subsequence of an entire melody, is asequence of integers in our representation. A subsequence of a melody is atheme if it:
is at least five notes long
appears (potentially transposed -- see below) again somewhere else in the piece of music
is disjoint from (i.e., non-overlapping with) at least one of its other appearance(s)
Transposed means that a constant positive or negative value is added to everynote value in the theme subsequence.
Given a melody, compute the length (number of notes) of the longest theme.
One second time limit for this problem's solutions!
Input
The input containsseveral test cases. The first line of each test case contains the integer N.The following n integers represent the sequence of notes.
The last test case is followed by one zero.
Output
For each testcase, the output file should contain a single line with a single integer thatrepresents the length of the longest theme. If there are no themes, output 0.
Sample Input
30
25 27 30 34 39 45 52 60 69 79 69 60 52 4539 34 30 26 22 18
82 78 74 70 66 67 64 60 65 80
0
Sample Output
5
题目大意:给n个数。数字都在1~88之间。现在求出最长的两段数字,满足一段数字每个数同时加(减)一个数可以得到另一段数字。这样的数字串最短为5.
方法:对于n<10可以直接输出。而对于加(减)一个数得到另一段数字,可以想到,两段数字串分别对相邻位做差得到的数字串恰好相等。即 2 4 9 7 8 10 13可以看出2 4 6相邻位做差为2
3,8 10 12相邻位做差也是2 3.这样就可以做差之后求出最大height值,并保证没有重叠,答案即是最大height值+1.再求height值是,我们可以通过二分height,判断是否存在满足条件的height。
A musical melodyis represented as a sequence of N (1<=N<=20000)notes that are integers inthe range 1..88, each representing a key on the piano. It is unfortunate buttrue that this representation of melodies ignores
the notion of musical timing;but, this programming task is about notes and not timings.
Many composers structure their music around a repeating&qout;theme&qout;, which, being a subsequence of an entire melody, is asequence of integers in our representation. A subsequence of a melody is atheme if it:
is at least five notes long
appears (potentially transposed -- see below) again somewhere else in the piece of music
is disjoint from (i.e., non-overlapping with) at least one of its other appearance(s)
Transposed means that a constant positive or negative value is added to everynote value in the theme subsequence.
Given a melody, compute the length (number of notes) of the longest theme.
One second time limit for this problem's solutions!
Input
The input containsseveral test cases. The first line of each test case contains the integer N.The following n integers represent the sequence of notes.
The last test case is followed by one zero.
Output
For each testcase, the output file should contain a single line with a single integer thatrepresents the length of the longest theme. If there are no themes, output 0.
Sample Input
30
25 27 30 34 39 45 52 60 69 79 69 60 52 4539 34 30 26 22 18
82 78 74 70 66 67 64 60 65 80
0
Sample Output
5
题目大意:给n个数。数字都在1~88之间。现在求出最长的两段数字,满足一段数字每个数同时加(减)一个数可以得到另一段数字。这样的数字串最短为5.
方法:对于n<10可以直接输出。而对于加(减)一个数得到另一段数字,可以想到,两段数字串分别对相邻位做差得到的数字串恰好相等。即 2 4 9 7 8 10 13可以看出2 4 6相邻位做差为2
3,8 10 12相邻位做差也是2 3.这样就可以做差之后求出最大height值,并保证没有重叠,答案即是最大height值+1.再求height值是,我们可以通过二分height,判断是否存在满足条件的height。
#include <iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<string> #define MAX 20010 using namespace std; int wa[MAX] ,wb[MAX] ,wv[MAX] ,ws1[MAX] ,sa[MAX]; int rank1[MAX],height[MAX] ,num[MAX]; int cmp(int *r,int a,int b,int l) { return r[a]==r[b]&&r[a+l]==r[b+l]; } void da(int *r,int *sa ,int n,int m) { int i,j,p,*x=wa,*y=wb,*t; for(i=0;i<m;i++) ws1[i]=0; for(i=0;i<n;i++) ws1[x[i]=r[i]]++; for(i=1;i<m;i++) ws1[i]+=ws1[i-1]; for(i=n-1;i>=0;i--) sa[--ws1[x[i]]]=i; for(j=1,p=1;p<n;j*=2,m=p) { for(p=0,i=n-j;i<n;i++) y[p++]=i; for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j; for(i=0;i<n;i++) wv[i]=x[y[i]]; for(i=0;i<m;i++) ws1[i]=0; for(i=0;i<n;i++) ws1[wv[i]]++; for(i=1;i<m;i++) ws1[i]+=ws1[i-1]; for(i=n-1;i>=0;i--) sa[--ws1[wv[i]]]=y[i]; for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; } return; } void calheight(int *r,int *sa ,int n) { int i,j,k=0; for(i=1;i<=n;i++) rank1[sa[i]]=i; for(i=0;i<n;height[rank1[i++]]=k) for(k?k--:0,j=sa[rank1[i]-1];r[i+k]==r[j+k];k++); return; } int main() { int len ,len1 ,max1 ,n; while(scanf("%d",&n),n) { scanf("%d",&num[0]); for(int i = 1;i < n;i++) { scanf("%d",&num[i]); num[i-1] = num[i] - num[i-1] + 88; } if(n<10) { printf("0\n"); continue; } num[n-1] = 0; da(num,sa,n,177); calheight(num,sa,n-1); int flag ,left = 4 ,right = n ,sum = 0 ,min1 ,max1; while(left<=right) { int mid = (left + right) / 2; flag = 0; for(int i = 0;i<n-1;i++) { if(height[i]>=mid) { min1 = min(sa[i-1],sa[i]); max1 = max(sa[i-1],sa[i]); if(max1 - min1 > mid) { flag = 1; break; } while(height[i]>=mid) { min1 = min(min1,sa[i]); max1 = max(max1,sa[i]); i++; if(max1 - min1 > mid) { flag = 1; break; } } } } if(!flag) { right = mid - 1; } else { sum = mid; left = mid + 1; } } if(!sum) { printf("%d\n",sum); } else { printf("%d\n",sum+1); } } return 0; }
相关文章推荐
- 后缀数组 POJ 1743 Musical Theme
- POJ 1743 Musical Theme <后缀数组+二分>
- POJ 1743 Musical Theme 后缀数组 不可重叠最长反复子串
- POJ 1743 Musical Theme
- POJ 1743 Musical Theme (不可重叠最长重复子串)
- poj 1743 Musical Theme (后缀数组)
- POJ 1743 Musical Theme
- POJ 1743 - Musical Theme 最长不重叠重复子串
- poj 1743 Musical Theme (后缀数组+二分答案)
- POJ1743 Musical Theme [后缀自动机]
- 【后缀数组】[POJ1743]Musical Theme 乐曲主旋律
- poj1743 Musical Theme
- POJ 1743 Musical Theme - 后缀数组
- POJ - 1743 Musical Theme 后缀数组 二分
- poj 1743 Musical Theme
- poj 1743 Musical Theme (后缀数组 不可重叠最长重复子串)
- POJ 1743 Musical Theme (字符串HASH+二分)
- 【POJ 1743】Musical Theme
- POJ1743 Musical Theme
- POJ 1743 Musical Theme (后缀数组)