PTA 11-散列4 Hard Version (30分)
题目地址
https://pta.patest.cn/pta/test/16/exam/4/question/680
5-18 Hashing - Hard Version (30分)
Given a hash table of size NN, we can define a hash function . Suppose that the linear probing is used to solve collisions, we can easily obtain the status of the hash table with a given sequence of input numbers.
However, now you are asked to solve the reversed problem: reconstruct the input sequence from the given status of the hash table. Whenever there are multiple choices, the smallest number is always taken.
Input Specification:
Each input file contains one test case. For each test case, the first line contains a positive integer NN (\le 1000≤1000), which is the size of the hash table. The next line contains NN integers, separated by a space. A negative integer represents an empty cell in the hash table. It is guaranteed that all the non-negative integers are distinct in the table.
Output Specification:
For each test case, print a line that contains the input sequence, with the numbers separated by a space. Notice that there must be no extra space at the end of each line.
Sample Input:
11
33 1 13 12 34 38 27 22 32 -1 21
Sample Output:
1 13 12 21 33 34 38 27 22 32
根据hash表算原始的插入顺序,很有意思的题,mooc讲了思路。
/*
评测结果
时间 结果 得分 题目 编译器 用时(ms) 内存(MB) 用户
2017-07-08 11:46 答案正确 30 5-18 gcc 6 4
测试点结果
测试点 结果 得分/满分 用时(ms) 内存(MB)
测试点1 答案正确 18/18 2 1
测试点2 答案正确 4/4 2 1
测试点3 答案正确 2/2 2 1
测试点4 答案正确 2/2 2 1
测试点5 答案正确 4/4 6 4 刚开始找应该输出的点时,暴力扫描取最小,结果发现第三个点超时
后来改用堆找最小结点
发现还是超时。。。
然后没辙了,找了个带注释的测试点截图,第三个点写到,有非-1的空位 WTF! 改了之后发现这个数据量,用暴力扫最小结点耗时也是十几毫秒,没慢多少,但是按理说还是用堆比较科学。
————————————————
读入hash表-> 表里i位置上的元素,如果算完hash应该插在j位置上,那么从i-1,一直减到j,这些元素都要在i之前插入。
用(i-1+N)%N解决hash表的循环问题 把依赖关系计算完后,此时问题就成了拓扑排序。
再接下来就是怎么找入度为0的结点中,包含元素最小的点了。
此解法建了堆,最开始把入度为0的全部提前压进去,然后开始循环往外取。
取出后断开该结点发出的边与其它点的连接。如果断开后发现其它结点入度变成了0,那么立即把该入度为0的点扔到堆里。
*/
#include<stdio.h>
#define TRUE 1
#define FALSE 0
#define MAXN 1000
#define EMPTY -1
#define INFINITY 6666666 struct HashNode
{
int value;
int visited; //是否访问过
int noCollision; //是否有冲突,建矩阵的时候用
int indegree; //入度
} gHashTable[MAXN]; int gMatrix[MAXN][MAXN];
int Heap[MAXN+1]; //堆
int HeapLength=0; //堆长 void DBG_printHeap() //debug时打印堆的
{
int i;
for(i=1;i<=HeapLength;i++)
{
printf("%d ",gHashTable[Heap[i]].value);
}
printf("+++++\n");
}
void InsertIntoHeap(int a) //插入堆
{
int i;
Heap[++HeapLength]=a;
i=HeapLength;
while(i/2>0)
{
if(gHashTable[Heap[i/2]].value>gHashTable[a].value)
{
Heap[i]=Heap[i/2];
i=i/2;
}
else break;
}
Heap[i]=a;
// DBG_printHeap();
} int DeHeap() //弹出堆顶
{
if(HeapLength==0)
return EMPTY;
int top=Heap[1];
int temp,parent,child;
Heap[1]=Heap[HeapLength--];
temp=Heap[1];
for(parent=1;2*parent<=HeapLength;parent=child)
{
child=parent*2;
if(child!=HeapLength)
{
if(gHashTable[Heap[child]].value>gHashTable[Heap[child+1]].value)
child++;
} if(gHashTable[temp].value>gHashTable[Heap[child]].value)
Heap[parent]=Heap[child];
else break;
}
Heap[parent]=temp;
// DBG_printHeap();
return top;
} void CalcMatrix(int N) //计算依赖关系的邻接矩阵
{
int i,idx,p;
for(i=0;i<N;i++)
{
if(gHashTable[i].noCollision==1 || gHashTable[i].value==EMPTY)
continue;
idx=gHashTable[i].value%N;
p=(i-1+N)%N;
while(p!=idx)
{
if(gHashTable[p].value!=EMPTY)
gMatrix[p][i]=TRUE;
gHashTable[i].indegree++;
p=(p-1+N)%N;
}
gMatrix[idx][i]=TRUE;
gHashTable[i].indegree++;
}
} void DeleteEdges(int idx,int N) //删边
{
int i;
for(i=0;i<N;i++)
{
if(gMatrix[idx][i])
{
// gMatrix[idx][i]=FALSE;
gHashTable[i].indegree--;
if(gHashTable[i].indegree==0)
{
// gHashTable[i].visited=TRUE;
InsertIntoHeap(i);
}
}
}
// gHashTable[idx].visited=TRUE;
} int InitHeapBeforePop(int N) //最开始时扫描结点,把入度为零的扔堆里面
{
int i; for(i=0;i<N;i++)
{
if(gHashTable[i].visited==TRUE || gHashTable[i].indegree!=0)
continue;
else
InsertIntoHeap(i);
}
} int main()
{
int N,i,temp,firstprint;
scanf("%d",&N);
for(i=0;i<N;i++)
{
scanf("%d",&gHashTable[i].value);
if(gHashTable[i].value%N==i)
gHashTable[i].noCollision=TRUE;// 下标和hash值相符,说明没冲突
if(gHashTable[i].value<0)
gHashTable[i].value=EMPTY; //标识空位
if(gHashTable[i].value==EMPTY)
gHashTable[i].visited=TRUE; //把空位的visited置1,后续不处理
}
CalcMatrix(N);
InitHeapBeforePop(N);
firstprint=1; //处理格式问题,第一个字符前面不加空格
while((temp=DeHeap()) != EMPTY)
{
DeleteEdges(temp,N);
if(!firstprint)
putchar(' ');
printf("%d",gHashTable[temp].value);
firstprint=0;
}
}
PTA 11-散列4 Hard Version (30分)的更多相关文章
- PTA 07-图5 Saving James Bond - Hard Version (30分)
07-图5 Saving James Bond - Hard Version (30分) This time let us consider the situation in the movie ...
- PTA 7-1 是否完全二叉搜索树 (30分)
PTA 7-1 是否完全二叉搜索树 (30分) 将一系列给定数字顺序插入一个初始为空的二叉搜索树(定义为左子树键值大,右子树键值小),你需要判断最后的树是否一棵完全二叉树,并且给出其层序遍历的结果. ...
- PTA二叉搜索树的操作集 (30分)
PTA二叉搜索树的操作集 (30分) 本题要求实现给定二叉搜索树的5种常用操作. 函数接口定义: BinTree Insert( BinTree BST, ElementType X ); BinTr ...
- PTA 逆散列问题 (30 分)(贪心)
题目链接:https://pintia.cn/problem-sets/1107178288721649664/problems/1107178432099737614 题目大意: 给定长度为 N 的 ...
- 11-散列4 Hashing - Hard Version (30 分)
Given a hash table of size N, we can define a hash function H(x)=x%N. Suppose that the linear probin ...
- JavaScript数据结构-11.散列
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- PTA 最大子列和问题(10 分)
最大子列和问题(10 分) 给定K个整数组成的序列{ N1, N2, ..., NK },“连续子列”被定义为{ Ni, Ni+1, ..., Nj },其中 1≤ ...
- 纯数据结构Java实现(11/11)(散列)
欢迎访问我的自建博客: CH-YK Blog.
- 07-图5 Saving James Bond - Hard Version (30 分)
This time let us consider the situation in the movie "Live and Let Die" in which James Bon ...
随机推荐
- Selenium3+webdriver学习笔记4(css方式元素定位)
#!/usr/bin/env python# -*- coding:utf-8 -*- from selenium import webdriver import time,os # about:ad ...
- Linux中gzip、bzip2、zip、unzip、tar使用介绍
压缩解压缩命令介绍.gz 压缩为gzip文件.bz2 压缩为bzip2文件.tar 打包文件,将多个文件合并成一个目录.tar.gz 先打成tar包,再压缩为gzip文件.tar.bz2 先打成tar ...
- android测试开发环境搭建
本文档针对未接触过android的0基础人员,在开始熟悉android之前,首先需要一个学习环境来支撑,在此简单介绍一下android环境搭建.(当然大家也可以百度.谷歌,类似的文档很多) 环境搭建: ...
- HDU 2639 Bone Collector II (01背包,第k解)
题意: 数据是常规的01背包,但是求的不是最大容量限制下的最佳解,而是第k佳解. 思路: 有两种解法: 1)网上普遍用的O(V*K*N). 2)先用常规01背包的方法求出背包容量限制下能装的最大价值m ...
- windows server 2008 r2 启用 Windows Defender
单击“开始”,指向“管理工具”,然后单击“服务器管理器”. 在“服务器管理器”中,单击“功能”,然后在“服务器管理器”细节窗格中的“功能摘要”下,单击“添加功能”. 此时会启动“添加功能向导”. 在“ ...
- 卓越管理的实践技巧(4)如何才能给予有效的反馈 Guide to Giving Effective Feedback
Guide to Giving Effective Feedback 前文卓越管理的秘密(Behind Closed Doors)最后一部分提到了总结的13条卓越管理的实践技巧并列出了所有实践技巧名称 ...
- cookie和session是否可以保存对象
session看了一下,是可以保存对象的.语法很普通,但是cookie的话本身是只能保存string类型的信息的,这就需要先序列化,然后接收的页面反序列化后形成对象调用,为了防止乱码,需要在数据传输的 ...
- nginx之HTTP模块配置
listen 指令只能使用与server字段里 如果本地调用可以监听本地Unix套接字文件,性能更加,因为不用走内核网络协议栈 listen unix:/var/run/nginx.sock; ...
- 使用EventLog组件保存Windows系统日志
实现效果: 知识运用: EventLog类的CreateEventSource方法 //用于建立一个应用程序 使用指定的Sourc作为向本机上的日志中写入日志项的有效事件源 CreateEventS ...
- docker单主机网络
当你安装Docker时,它会自动创建三个网络.你可以使用以下docker network ls命令列出这些网络: [root@localhost ~]# docker network ls NETWO ...