# 欢乐的跳
## 题目描述
一个 n 个元素的整数数组,如果数组两个连续元素之间差的绝对值包括了 [1,n-1] 之间的所有整数,则称之符合“欢乐的跳”,如数组 {1,4,2,3}符合“欢乐的跳”,因为差的绝对值分别为:3,2,1。
给定一个数组,你的任务是判断该数组是否符合“欢乐的跳”。
## 输入格式
每组测试数据第一行以一个整数 n(1 n 1000) 开始,接下来 n 个空格隔开的在 [-10^8,10^8] 之间的整数。
## 输出格式
对于每组测试数据,输出一行若该数组符合“欢乐的跳”则输出 `Jolly`,否则输出 `Not jolly`。
## 样例 #1
### 样例输入 #1
```
4 1 4 2 3
```
### 样例输出 #1
```
Jolly
```
## 样例 #2
### 样例输入 #2
```
5 1 4 2 -1 6
```
### 样例输出 #2
```
Not jolly
```
## 提示
1 n 1000
这道题看起来简单,但是我相信大部人都忽略了一个问题,即他的值域为1e-8~1e8。这样的话,再求差的时候可能会产生一个非常大的数,用这样的大的数作为数组的下标,显然不合适,而我们可以通过哈希的方式将这个值变为一个较小的数,代码如下:
#include <iostream>
using namespace std;
#include <algorithm>
#include <cmath>
#include <cstring>
const int N = 1010,M = 2 * N,null = 0x3f3f3f3f;//一个极大的数,可以理解为无穷大
int a[N],h[M];
bool re[N];
int abs(int a, int b)
{
return (a - b <= 0) ? b - a : a - b;
}
int find(int x)
{
int k = x % N;
while (h[k] != null && h[k] != x)
{
k++;
if (k == N)k = 0;
}
return k;
}
int main()
{
int n;
cin >> n;
memset(h, 0x3f, sizeof(h));
for (int i = 0; i < n; i++)scanf("%d", &a[i]);
for (int i = 0; i < n - 1; i++)
{
int t = abs(a[i], a[i + 1]);
int m = find(t);//计算差值的哈希值
re[m] ++;//记录这个差值出现过
}
for (int i = 1; i < n; i++)
{
int g = find(i);//同理也要先求其哈希值
if (!re[g])
{
cout << "Not jolly" << endl;
return 0;
}
}
cout << "Jolly" << endl;
return 0;
}