首页 > 试题广场 >

音乐研究

[编程题]音乐研究
  • 热度指数:532 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
美团外卖的品牌代言人袋鼠先生最近正在进行音乐研究。他有两段音频,每段音频是一个表示音高的序列。现在袋鼠先生想要在第二段音频中找出与第一段音频最相近的部分。

具体地说,就是在第二段音频中找到一个长度和第一段音频相等且是连续的子序列,使得它们的 difference 最小。两段等长音频的 difference 定义为:
difference = SUM((a[i] - b[i])2 )(1 ≤ i ≤ n),其中SUM()表示求和
其中 n 表示序列长度,a[i], b[i]分别表示两段音频的音高。现在袋鼠先生想要知道,difference的最小值是多少?数据保证第一段音频的长度小于等于第二段音频的长度。

输入描述:
第一行一个整数n(1 ≤ n ≤ 1000),表示第一段音频的长度。
第二行n个整数表示第一段音频的音高(0 ≤ 音高 ≤ 1000)。
第三行一个整数m(1 ≤ n ≤ m ≤ 1000),表示第二段音频的长度。
第四行m个整数表示第二段音频的音高(0 ≤ 音高 ≤ 1000)。


输出描述:
输出difference的最小值
示例1

输入

2
1 2
4
3 1 2 4

输出

0
这么小的数据量,暴力滑窗就过了
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        String[] strs = br.readLine().split(" ");
        int[] a = new int[n];
        for(int i = 0; i < n; i++){
            a[i] = Integer.parseInt(strs[i]);
        }
        int m = Integer.parseInt(br.readLine());
        strs = br.readLine().split(" ");
        int[] b = new int[m];
        for(int i = 0; i < m; i++){
            b[i] = Integer.parseInt(strs[i]);
        }
        int min = Integer.MAX_VALUE;
        for(int i = 0; i <= m - n; i++){
            min = Math.min(min, getDifference(a, b, i, n));
        }
        System.out.println(min);
    }
    
    private static int getDifference(int[] a, int[] b, int start, int len) {
        int difference = 0;
        for(int i = start; i < start + len; i++){
            difference += (a[i - start] - b[i])*(a[i - start] - b[i]);
        }
        return difference;
    }
}

发表于 2022-01-10 20:44:14 回复(0)

暴力求解


#include <iostream>
 #include <vector>
 #include <math.h>
 using namespace std;

 int GetMinDiff(const vector<int>& sub, const vector<int>& lng)
 {
     int len1 = sub.size( ) ;
     int len2 = lng.size( ) ;
     if(len1 > len2) return -1;

     int min = 0x7fffffff, curDiff = 0;
     for(int i=0; i < len2-len1; ++i){
         int k = i;
         curDiff = 0;
         for(int j = 0; j< len1; ++j){
             int dif = abs(sub[j]-lng[k++]);
             curDiff += (int)pow((double)dif, (double)2);
         }
         if(min > curDiff){
             min = curDiff;
         }
     }
     return min;
 }

 int main( )
 {
     int n,m;
     while( cin>>n){
         vector<int> v1(n, 0);
         for(int i=0; i< n; ++i)
             cin>>v1[i];

         cin>>m;
         vector<int> v2(m, 0);
         for(int i=0; i< m; ++i)
             cin>>v2[i];
         cout<<GetMinDiff(v1, v2)<<endl;
     }
     return 0;
 }
发表于 2018-09-25 18:59:50 回复(0)
import java.util.Scanner;


public class Main {

public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[] song1 = new int[n];
for (int i = 0; i < n; i++) {
song1[i]=scanner.nextInt();
}
int m = scanner.nextInt();
int[] song2 = new int[m];
for (int i = 0; i < m; i++) {
song2[i]=scanner.nextInt();
}
long result = Long.MAX_VALUE;
for (int i = 0; i <= m-n; i++) {
long temp = 0;
for (int j = 0; j < n; j++) {
temp+=Math.pow(song1[j]-song2[i+j], 2);
}
if (temp<result) {
result = temp;
}
}
System.out.println(result);
scanner.close();
}

}

发表于 2017-06-18 01:38:07 回复(0)
import java.util.Scanner;

public class Main {
	public static int getDifference(int a[], int b[]) {
		int min = Integer.MAX_VALUE;
		int aLen = a.length;
		for (int i = 0; i <= b.length-aLen; i++) {
			int k = i;
			int difference = 0;
			for (int j = 0; j < aLen; j++) {
				int temp = a[j] - b[k];
				difference += temp * temp;
				if (difference > min)// 过滤掉不必要的执行
					break;
				k++;
				if (j == aLen - 1) {
					if (difference == 0)
						return 0;
					if (difference < min)
						min = difference;
				}
			}
		}
		return min;
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int[] a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = sc.nextInt();
		int m = sc.nextInt();
		int[] b = new int[m];
		for (int i = 0; i < m; i++)
			b[i] = sc.nextInt();
		System.out.println(getDifference(a, b));
	}
}

发表于 2017-06-17 21:38:06 回复(0)
n = int(input())
vdio1 = list(map(int, input().split()))
m = int(input())
vdio2 = list(map(int, input().split()))
differnce = []
for i in range(0, len(vdio2)-len(vdio1)+1):
    diff_sum = 0
    vd2 = vdio2[i:len(vdio1)+i]
    for (a, b) in zip(vdio1, vd2):
        diff_sum += (a-b)**2
    
    differnce.append(diff_sum)
 
print(min(differnce))
发表于 2020-04-23 18:21:50 回复(0)
def diff(a,b):
    res=[]
    for i in range(len(a)):
        res.append((a[i]-b[i])**2)
    return sum(res)
while True:
    try:
        n=input()
        if len(n)==0:
            break
        n=int(n)
        s1=list(map(int,input().split()))
        m=int(input())
        s2=list(map(int,input().split()))
        res=[]
        for i in range(m-n+1):
            c=[]    #c保存第二个列表中所有与第一个列表等长的子列表
            for j in range(n):
                c.append(s2[i+j])
            res.append(diff(s1,c))
        print(min(res))
    except:
        break
        

发表于 2019-04-23 13:18:20 回复(0)
#include<iostream>
#include<vector>

using namespace std;
int main(){
	int n,m,dif,d=0,sum=0;
	while(cin>>n){
	vector<int> a(n,0);
	for(int i=0;i<n;i++)
		cin>>a[i];
	cin>>m;
	vector<int> b(m,0);
	for(int i=0;i<m;i++)
		cin>>b[i];
	if(m>=n)
		dif=m-n;
	for(int i=0;i<dif;i++){
		sum=0;
		for(int j=0;j<n;j++){
			sum+=(a[j]-b[i+j])*(a[j]-b[i+j]);
			}
		if(i==0)d=sum;
		if(sum<d)
			d=sum;
		}
	cout<<d<<endl;
	}
	//system("pause");
	return 0;
}

发表于 2017-07-02 20:01:08 回复(0)
import java.util.Scanner;

public class Main {

    static final int MAX_DIFFENTCE = 1000 * 1000 * 1000;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int minDiffence = MAX_DIFFENTCE;
        int diffence = 0;
        int an = sc.nextInt();
        int[] a = new int[1000] ;
        //a[0...an)
        for(int i = 0; i < an; i++){
           a[i] = sc.nextInt();
        }
        int bn = sc.nextInt();
        int[] b = new int[1000] ;
        //b[0...bn)
        for(int i = 0; i < bn; i++){
           b[i] = sc.nextInt();
        }
        
        if(an > bn){
            minDiffence = MAX_DIFFENTCE;
            System.out.println(minDiffence);
            sc.close();
            return;
        }
        //计算总共偏移
        int m = bn - an + 1;
        for(int i = 0 ; i < m ; i++){//有m种可能性
            boolean flag = true;
            diffence = 0;
            for(int j = 0 ; j < an ; j++){
                int x = a[j] - b[j+i];
                int x2 = x * x;
                diffence += x2;
                if(diffence > minDiffence){
                    flag = false;
                    continue;
                }
            }
            if(flag){
                minDiffence = diffence;
            }
        }
        
        System.out.println(minDiffence);
    }


}

发表于 2017-06-18 21:15:21 回复(0)