欢乐的跳(哈希)

# 欢乐的跳

## 题目描述

一个 n 个元素的整数数组,如果数组两个连续元素之间差的绝对值包括了 [1,n-1] 之间的所有整数,则称之符合“欢乐的跳”,如数组 {1,4,2,3}符合“欢乐的跳”,因为差的绝对值分别为:3,2,1。

给定一个数组,你的任务是判断该数组是否符合“欢乐的跳”。

## 输入格式

每组测试数据第一行以一个整数 n(1 \leqslant n \leqslant 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 \leqslant n \leqslant 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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值