不适的曲调c++

题目描述
所有人都知道奶牛喜欢听所有种类的音乐。伟大的奶牛作曲家 Moozart 有次发现了一个特殊的和弦可以让奶牛感到不适。这个和弦就是著名的反刍动物第七和弦,因此所有的奶牛音乐作曲家都会特意回避它。

Farmer John 并不了解奶牛作曲史的细节,他打算在牛棚大声的播放他喜欢的音乐。你的任务就是在这首歌中识别出所有的反刍动物第七和弦,从而评估它会让奶牛感到有多不适。

FJ 播放的这首歌由一系列的 N 个音符组成,每个音符表示成一个范围在 [1 , 88] 内的整数。反刍动物第七和弦可以用 C 个独特的音符序列表示,每个音符也是范围在 [1 , 88] 内的整数。然而,即便这些音符是变调的(同时增加或者减少一个常数),或者重排的,它依旧是反刍动物第七和弦!例如,如果 4 , 6 , 7 是反刍动物第七和弦,那么 3, 5, 6(同时减 1 ), 6, 8, 9 (同时加 2 ), 6, 4, 7 (重排), 5, 3, 6(变调并重排) 都是反刍动物第七和弦。

一个反刍动物第七和弦就是满足上述标准的长为 C 的连续音符序列。因此它可以用其在歌曲中的起始位置进行唯一标识。请求出所有反刍动物第七和弦在歌曲中出现的起始位置。

输入格式
第 1 行:一个整数 N 。

第 2 ~ 1 + N 行: FJ 的歌曲的 N 个音符,每个音符一行。

第 2 + N 行:一个整数 C 。

第 3 + N ~ 2 + N + C 行:反刍动物第七和弦的 C 个音符样例。所有的变调或者重排都还是反刍动物第七和弦。

输出格式
第 1 行:一个数量 K ,表示 FJ 的歌中反刍动物第七和弦出现的次数。注意不同的和弦段是可以有重叠部分的。

第 2 ~ 1 + K 行:每行一个反刍动物第七和弦的起始下标( 1 是 FJ 的歌中的第一个音符, N 是最后一个)。下标需要按照升序排列。

如果歌曲中没有出现第七和弦,则输出 0 。

样例 #1
【样例输入 #1】
6
1
8
5
7
9
10
3
4
6
7
【样例输出 #1】
2
2
4
样例解释
FJ 的歌是 1, 8, 5, 7, 9, 10 ,一个反刍动物第七和弦是 4, 6, 7 的变调或者重排。

FJ 的歌中出现了两次反刍动物第七和弦(并且这两次出现有一个音符的重叠)。第一个是起点为 2 的 8 , 5 , 7(变 调 +1 并重排),第二个是起点为 4 的 7, 9, 10 (变调 +3 )。

数据范围
1 ≤ N ≤ 20000 , 1 ≤ C ≤ 10 。


思路:枚举排序
假设歌曲长度为N,第七和弦长度为M。基本思路就是在歌曲中不断拿出长度为M的连续串与第七和弦比较,看这个串能否由第七和弦变调、重排得出。
为了方便这种比较,可以先将第七和弦排序,每次枚举歌曲中长度为M的连续串时,也将这个串排序。
排序后的第七和弦与这个串进行比较时,看它们各自位置相同的相邻两个元素的差值是否一致即可。例如第七和弦为“4,6,7”,歌曲中某个长度为3的连续串为“8,5,7”,分别排序后对应的就是“4,6,7”和“5,7,8”。
在“4,6,7”中,6-4=2,7-6=1;
在“5,7,8”中,7-5=2,8-7=1。
由此可得,连续串“8,5,7”可以由第七和弦变调重排得出。


代码如下:

#include<bits/stdc++.h>
using namespace std;
int N,C,a[20005],b[15],c[15],d[15],e[15],flag = 1,dan[20005],k;
void bushidequdiao(){
	scanf("%d",&N);
	for(int i = 1;i <= N;i++){
		scanf("%d",&a[i]);
	}
	scanf("%d",&C);
	for(int i = 1;i <= C;i++){
		scanf("%d",&b[i]);
	}
	sort(b+1,b+1+C);
	for(int i = 1;i <= N-C+1;i++){
		flag = 1;
		for(int j = 1;j <= C;j++){
			c[j] = a[i+j-1];
		}
		sort(c+1,c+1+C);
		for(int j = 1;j <= C;j++){
		}
		for(int j = 1;j < C;j++){
			d[j] = c[j+1] - c[j];
			e[j] = b[j+1] - b[j];
			if(d[j] != e[j])	flag = 0;
		}
		if(flag){
			k++;
			dan[k] = i;
		}
	}
	if(k){
		printf("%d\n",k);
		for(int i = 1;i <= k;i++){
			printf("%d\n",dan[i]);
		}
	}
	else printf("0");
}
int main(){
	bushidequdiao();
	return 0;
}

运行结果:

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值