pat解题报告【1078】

1078. Hashing (25)

时间限制

100 ms

内存限制

32000 kB

代码长度限制

16000 B

判题程序

Standard

作者

CHEN, Yue

The task of this problem is simple: insert a sequence of distinct positive integers into a hash table, and output the positions of the input numbers.  The hash function is defined to be "H(key) = key % TSize" where TSize is the maximum size of the hash table. 
Quadratic probing (with positive increments only) is used to solve the collisions.

Note that the table size is better to be prime.  If the maximum size given by the user is not prime, you must re-define the table size to be the smallest prime number which is larger than the size given by the user.

Input Specification:

Each input file contains one test case.  For each case, the first line contains two positive numbers: MSize (<=104) and N (<=MSize) which are the user-defined table size and the number of input numbers, respectively. 
Then N distinct positive integers are given in the next line.  All the numbers in a line are separated by a space.

Output Specification:

For each test case, print the corresponding positions (index starts from 0) of the input numbers in one line.  All the numbers in a line are separated by a space, and there must be no extra space at the end of the line.  In case it is impossible to insert
the number, print "-" instead.

Sample Input:

4 4
10 6 4 15

Sample Output:

0 1 4 -

这题本质靠hash算法里面的二次试探法。h_new=(h_old+cc*cc)%sizet, cc=1,2,3,4······。h_old是原来的hash值,h_new是新得到的hash值。其实原来的二次试探法是双向的,刚开始我也按双向的做了。这个题目就坑在只要求正向增长试探,不要双向,双向会错。(with positive increments only)!!!

这个题目还有一点:要求hash表的大小是素数,如果不是素数那么取比这个数大的最小的素数。

这里涉及到素数生成算法和找对应的素数两个算法。

素数生成算法:

void init() {
	memset( vis, 0, sizeof( vis ) );
	memset( is_prime, 0, sizeof( is_prime ) );
	is_prime[0] = is_prime[1] = 1;
	int i, j;

	for ( i = 2; i < maxn; i++ ) {
		for ( j = 2; j * i < maxn; j++ )
			is_prime[i * j] = 1;
	}

   cnt = 0;

	for ( i = 2; i < maxn; i++ ) {
		if ( !is_prime[i] )
			prime[cnt++] = i;
	}
}

算素数网上有几种算法,比如说筛选法,相除法,这里用了一种比较朴素的思想,就是算出所有合数,用数组标记,那么剩下的就是素数。prime数组里面存的就是素数。

找对应的素数:

int find(int m,int left,int right){

	if (m<prime[left])// 考虑不再范围内的情况
	{
		return prime[left];
	}
	int mid=(left+right)/2;

	if(abs(right-left)<=1)
		return max(prime[right],prime[left]);
	if (m<prime[mid])
	{
		right=mid;
	    return find(m,left,right);
	}
	else
	{
		left=mid;
		return find(m,left,right);
	}
}

大致是二分查找的思想,这里有一种情况要注意;当原来的数不再最小素数和最大素数的区间时特殊处理。

代码:

// pat-1078.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include"algorithm"
#include "iostream"
#include "memory"
#include "math.h"
using namespace std;
#define maxn  50000
int vis[maxn];
int is_prime[maxn];
int prime[maxn];
int cnt=0;
void init() {
	memset( vis, 0, sizeof( vis ) );
	memset( is_prime, 0, sizeof( is_prime ) );
	is_prime[0] = is_prime[1] = 1;
	int i, j;

	for ( i = 2; i < maxn; i++ ) {
		for ( j = 2; j * i < maxn; j++ )
			is_prime[i * j] = 1;
	}

   cnt = 0;

	for ( i = 2; i < maxn; i++ ) {
		if ( !is_prime[i] )
			prime[cnt++] = i;
	}
}
int find(int m,int left,int right){

	if (m<prime[left])// 考虑不再范围内的情况
	{
		return prime[left];
	}
	int mid=(left+right)/2;

	if(abs(right-left)<=1)
		return max(prime[right],prime[left]);
	if (m<prime[mid])
	{
		right=mid;
	    return find(m,left,right);
	}
	else
	{
		left=mid;
		return find(m,left,right);
	}
}

int main()
{
	init();
	bool first=true;
	int m=0,n=0,sizet=0;
	cin>>m>>n;
	if (is_prime[m])//非素数
	{
		int left=0,right=cnt-1;
		sizet=find(m,left,right);
	}
	else
	sizet=m;
	int *visit=new int[sizet];
	memset(visit,0,sizeof(int)*sizet);//开数组大小注意是sizet
	for (int i=0;i<n;i++)
	{
		int temp=0,h=0;
		cin>>temp;
		h=temp%sizet;
		int htemp=h;
		int cc=0.0;
		while (visit[h]==1&&cc<((sizet)/2))//发生冲突
		{
			cc++;
			//h=(temp+cc*cc)%sizet;
			h=(htemp+cc*cc)%sizet;//二次试探
		}
		if(cc<((sizet)/2)&&(!visit[h]))
		{
			if (first)
			{
				cout<<h;
				first=false;
			}
			else
				cout<<" "<<h;
			visit[h]=1;//已经被访问了
		}
		else//不能
		{
			if (first)
			{
				cout<<"-";
				first=false;
			}
			else
				cout<<" "<<"-";
		}

	}
	cout<<endl;
	return 0;
}

pat解题报告【1078】,布布扣,bubuko.com

时间: 2024-08-08 04:01:51

pat解题报告【1078】的相关文章

pat解题报告【1074】

1074. Reversing Linked List (25) 时间限制 300 ms 内存限制 32000 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elements on L.  For example, given L being 1→2→3→4→5→

pat解题报告【1073】

1073. Scientific Notation (20) 时间限制 100 ms 内存限制 32000 kB 代码长度限制 16000 B 判题程序 Standard 作者 HOU, Qiming Scientific notation is the way that scientists easily handle very large numbers or very small numbers.  The notation matches the regular expression [

pat解题报告【1082】

1082. Read Number in Chinese (25) 时间限制 400 ms 内存限制 32000 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Given an integer with no more than 9 digits, you are supposed to read it in the traditional Chinese way.  Output "Fu" first if it is negative. 

2016.8.29 解题报告之我会做的题都是简单题

老规矩,要相关资料联系邮箱: 考试分析: 1.  画图确定性质,其实我开始也打算用二进制判重的,但进制题一般不会使状态无法用longlong表示出来,然后那种确定了某种状态以后就排除了无关变量,直接取最优的思路也很不错: 2.  最早入手的题以及死在上面的题,还想了了很久的复杂度证明和对拍,无话可说,希望这次AK之路被断能让我涨一点记性,以后要抓住脑海里的每一点信息(本来还想了longlong这个问题的): 3.  找性质,把在线决策问题转化为线性判断类问题,排除任务之间有一点橡树的关系的无关干

解题报告 之 POJ3057 Evacuation

解题报告 之 POJ3057 Evacuation Description Fires can be disastrous, especially when a fire breaks out in a room that is completely filled with people. Rooms usually have a couple of exits and emergency exits, but with everyone rushing out at the same time

hdu 1541 Stars 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1541 题目意思:有 N 颗星星,每颗星星都有各自的等级.给出每颗星星的坐标(x, y),它的等级由所有比它低层(或者同层)的或者在它左手边的星星数决定.计算出每个等级(0 ~ n-1)的星星各有多少颗. 我只能说,题目换了一下就不会变通了,泪~~~~ 星星的分布是不是很像树状数组呢~~~没错,就是树状数组题来滴! 按照题目输入,当前星星与后面的星星没有关系.所以只要把 x 之前的横坐标加起来就可以了

【百度之星2014~初赛(第二轮)解题报告】Chess

声明 笔者最近意外的发现 笔者的个人网站http://tiankonguse.com/ 的很多文章被其它网站转载,但是转载时未声明文章来源或参考自 http://tiankonguse.com/ 网站,因此,笔者添加此条声明. 郑重声明:这篇记录<[百度之星2014~初赛(第二轮)解题报告]Chess>转载自 http://tiankonguse.com/ 的这条记录:http://tiankonguse.com/record/record.php?id=667 前言 最近要毕业了,有半年没做

2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告

2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告 勘误1:第6题第4个 if最后一个条件粗心写错了,答案应为1580. 条件应为abs(a[3]-a[7])!=1,宝宝心理苦啊.!感谢zzh童鞋的提醒. 勘误2:第7题在推断连通的时候条件写错了,后两个if条件中是应该是<=12 落了一个等于号.正确答案应为116. 1.煤球数目 有一堆煤球.堆成三角棱锥形.详细: 第一层放1个, 第二层3个(排列成三角形), 第三层6个(排列成三角形), 第四层10个(排列成三角形). -. 假设一共

[noip2011]铺地毯(carpet)解题报告

最近在写noip2011的题,备战noip,先给自己加个油! 下面是noip2011的试题和自己的解题报告,希望对大家有帮助,题目1如下 1.铺地毯(carpet.cpp/c/pas) [问题描述]为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯.一共有n 张地毯,编号从1 到n.现在将这些地毯按照编号从小到大的顺序平行于坐标轴先后铺设,后铺的地毯覆盖在前面已经铺好的地毯之上.地毯铺设完成后,组织者想知道覆盖地面某个点的最上面的那张地毯的