P4305 [JLOI2011]不重复数字(hash)

题目

题目传送门
在这里插入图片描述

题解

  • h a s h hash hash代替桶排序,判断每个数字是否出现直接输出即可

code

#include <bits/stdc++.h> 
using namespace std; 
typedef long long LL; 
const int maxn = 5e4 + 100; 

template <typename T> 
inline void read(T &s) {
	s = 0; 
	T w = 1, ch = getchar(); 
	while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); }
	while (isdigit(ch)) { s = (s << 1) + (s << 3) + (ch ^ 48); ch = getchar(); }
	s *= w; 
}

int t, n; 
int h[maxn]; 
const int mod = 100003; 

inline int ha(LL x) { return x % mod; } 

inline int find(LL x) {
	int y = ha(abs(x)); 
	while (h[x] && h[x] != x) ha(++y); 
	return y;  
}

inline void insert(LL x) { h[find(x)] = x; }
inline bool check(LL x) { return h[find(x)] == x; }

int main() {
	read(t); 
	while (t--) {
		memset(h, 0, sizeof(h)); 
		read(n); 
		for (int i = 1; i <= n; ++i) { 
			int x; read(x); 
			if (check(x)) continue; 
			printf("%d ", x); 
			insert(x); 
		} 
		putchar('\n'); 
	}
	return 0; 
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
如果您要在指定范围内找到最少重复或不重复数字,可以使用类似于二分查找的思路,将指定范围一分为二,然后递归地处理左半部分和右半部分,直到找到最少重复或不重复数字。 具体来说,您可以按照以下步骤操作: 1. 首先,定义一个函数,该函数接受两个参数:指定范围的左端点和右端点。 2. 然后,使用一个哈希表记录指定范围内每个数字的出现次数。 3. 接着,使用一个循环遍历指定范围内的所有数字,找到出现次数为 1 的数字的数量,并记录当前范围内的最少重复或不重复数字的数量。 4. 如果当前范围内的最少重复或不重复数字的数量为 1,则返回其中任何一个数字即可。 5. 否则,将指定范围一分为二,并递归地处理左半部分和右半部分,直到找到最少重复或不重复数字。 具体来说,您可以按照以下步骤操作: ``` def find_least_repeated_number(left, right): # 如果左端点等于右端点,则返回其中任何一个数字即可 if left == right: return left # 将指定范围一分为二 mid = (left + right) // 2 # 处理左半部分和右半部分 left_result = find_least_repeated_number(left, mid) right_result = find_least_repeated_number(mid + 1, right) # 如果左半部分和右半部分返回的结果相同,则返回其中任何一个数字即可 if left_result == right_result: return left_result # 否则,使用哈希表记录指定范围内每个数字的出现次数 hash_table = {} for i in range(left, right + 1): if i not in hash_table: hash_table[i] = 1 else: hash_table[i] += 1 # 使用一个循环遍历指定范围内的所有数字,找到出现次数为 1 的数字的数量,并记录当前范围内的最少重复或不重复数字的数量 count = 0 for num in hash_table: if hash_table[num] == 1: count += 1 if count == 1: for num in hash_table: if hash_table[num] == 1: return num else: return left_result if left_result is not None else right_result ``` 需要注意的是,如果指定范围非常大,递归算法可能会导致栈溢出。因此,您可以考虑使用迭代算法或尾递归优化来避免这种情况。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值