Description
平面直角坐标系上有n个点(n<100000)的点集P,现在有m个点要你判断是否在这个点集P上。
Input
只有一个案例,第一个数是n,接着有2n个数,表示n个点的坐标,然后,是一个一数m,后面有2m个点。这些点的坐标都是整数。
Ouput
按序输出这2m个点的状态,在点集P上就输出“Yes“,否则就输出“No”。
Sample Input
10
1 2
2 3
3 4
5 6
4 4
6 60
56 7
-8 9
99 9
-3 -4
3
1 1
99 9
-8 0
Sample Output
No
Yes
No
简单思路:用哈希表查询,时间复杂度是O(1),因此这个方法很有用。本题使用哈希表来查找点:先将一组点输入,在输入的同时创建哈希表,如果遇到冲突(如:(3,4)与(-3,-4),将(-3,-4)放在(3,4)的后面,用链表的方式连接),输入点判断时的过程应该与创建的过程一致。
源代码:
#include <iostream>
#include <cmath>
using namespace std;
const int size = 200002;
struct Point
{
int x,y;
Point *next;
};
Point hash[size];
int mark[size];
void insert(int x,int y)
{
Point *s,*p;
int i = fabs(x);
if(mark[i] == 0)
{
hash[i].x = x; hash[i].y = y;
mark[i] = 1;
}
else
{
p = &hash[i];
while(p->next != NULL)
p=p->next;
s=new Point;
s->x = x; s->y = y;
p->next = s;
s->next = NULL;
}
}
bool find(int x,int y)
{
Point *p;
int i = fabs(x);
if(mark[i] == 1)
{
p = &hash[i];
while(p != NULL)
{
if(p->x == x && p->y == y) return true;
p=p->next;
}
return false;
}
else return false;
}
int main()
{
int i,n,m;
int x,y;
for(i = 0; i < size; i++)
{
mark[i] = 0;
hash[i].x = -1; hash[i].y = -1;
}
cin>>n;
for(i = 0; i < n; i++)
{
cin>>x>>y;
insert(x,y);
}
cin>>m;
for(i = 0; i < m; i++)
{
cin>>x>>y;
if(find(x,y)) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}
大一的时候写的,现在从网易博客移过来~