Hash Function

原题链接

 错误原因

简单认为当前位置的下一个位置一定是可以放的,故将其直接放入优先队列

可看以下三组数据

10

-1 -1 -1 -1 24 5 6 7 14 -1

10

19 101 -1 -1 24 -1 -1 -1 8 9

10

-1 -1 -1 3 14 5 6 7 13 -1

正确思路

1. 可以先把hash值等于所在位置的数放入优先队列 ,类似于拓扑排序

2. 当从优先队列取出一个元素后,将当前位置所在位置的连通块与下一个位置所在连通块连接,使用并查集来处理

3. 判断连接之后的根节点是否能够放入优先队列,能够放入当根节点值不为-1且未被放入过优先队列且根节点值的哈希值的根节点等于根节点

正确代码

#include <bits/stdc++.h>
#define FastIO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;

const char sp = 32, cr = 10;
const int inf = 0x3f3f3f3f;
const int N = 2e5 + 5, M = 1e5;

int a[N], n, fa[N], ans[N], cnt;
bool vis[N];		//标记每个点只能入队列一次
priority_queue<PII, vector<PII>, greater<PII>> pq;
int find(int x) {
	return fa[x] == x ? x : fa[x] = find(fa[x]);
}
int main() {
	int t;
	cin >> t;
	while (t--) {
		memset(a, 0xff, sizeof(a));
		memset(vis, 0, sizeof(vis));
		cin >> n;
		cnt = 0;
		for (int i = 0;i < n;++i)	cin >> a[i];

		int num = 0;
		for (int i = 0;i < n;++i) {
			fa[i] = i;
			if (a[i] != -1) ++num;
			if (a[i] != -1 && a[i] % n == i) {
				vis[i] = true;
				pq.push({ a[i],i });
			}
		}

		while (!pq.empty()) {
			PII pii = pq.top();pq.pop();
			int x = pii.first, y = pii.second;
			ans[cnt++] = x;
			int p = fa[find(y)] = fa[find((y + 1) % n)];	//将当前块与下一个块链接起来
			//首先保证下个位置不为空,然后是没有入过队列,最后是从本来位置到下个位置连通,说明下个位置能放
			if (a[p] != -1 && !vis[p] && find(a[p] % n) == p) {
				vis[p] = true;
				pq.push({ a[p],p });
			}
		}
		if (cnt < num) cout << -1;		//此时出现了一些不在其本来位置并且前面存在空位的数字,这是无法达到的
		else for (int i = 0;i < cnt;++i) cout << ans[i] << sp;
		cout << cr;
	}



	return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值