题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=138
题目描述:
描述-
输入
-
第一行有一个整数n(0<n<=10000);
随后有n行;
每行可能出现如下的任意一种形式:
第一种:
一个字符串"ADD",接着是一个整数m,随后有m个i;
第二种:
一个字符串"QUERY”,接着是一个整数M,随后有M个ki;
输出
- 输出每次询问的结果"YES"或"NO".
2 ADD 5 34 343 54 6 2 QUERY 4 34 54 33 66
YES YES NO NO
题目分析:这里只需要在最短的时间内完成查找的任务,那么无疑,我们设计的算法的时间复杂度最好为O(1)。这里很容易可以确定用HashTable来存储球的编号。对于hash表的详细介绍可在blog:http://blog.youkuaiyun.com/cyongxue/article/details/19544107。那么,假设每个hash表至多存放50个球,而球的总数为10^8个,那么可以创建10^8/50= 2*10^6个hash表,故mod2*10^6即可将球映射到在应的hash表中。
代码如下:
// 找球号.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<stdio.h>
#include<string.h>
typedef struct HashNode
{
int nValue;
struct HashNode *next;
}HashNode;
HashNode *hashTable[N];
const int N = 1000002;
const unsigned int MAX = 200003;
int Hash[N];
int Head[N];//相当于每一个散列表的头节点
int Next[N];//当前节点的下一个节点
void Hash_Init()
{
memset(hashTable,NULL,N);
}
void Add(int num)
{
int key = num % MAX;
HashNode *pHead = hashTable[key];
HashNode *tmp = pHead->next;
while(tmp)
{
if(tmp->nValue == num)
return;
else
tmp = tmp->next;
}
HashNode *newNode = new HashNode;
newNode->nValue = num;
newNode->next = pHead->next;
pHead->next = newNode;
}
bool Query(int num)
{
int key = num % MAX;
bool isExisted = false;
HashNode *pHead = hashTable[key];
HashNode *tmp = pHead->next;
while(tmp)
{
if(tmp->nValue == num)
isExisted = true;
else
tmp = tmp->next;
}
return isExisted;
}
int main()
{
int t,i,n,a;
Hash_Init();
char str[10];
scanf("%d",&t);
while(t--)
{
scanf("%s %d", &str, &n);
if(str[0] == 'A')
{
for(i = 0; i < n; ++i)
{
scanf("%d", &a);
Add(a);
}
}
else if(str[0] == 'Q')
{
for(i = 0; i < n; ++i)
{
scanf("%d", &a);
if(Query(a))
printf("YES\n");
else
printf("NO\n");
}
}//end if
}//end while
return 0;
}