PIPI OJ 1334: PIPI计数(unordered_map的应用)

菜鸟生成记(57)

1334: PIPI计数

本以为就是一个简单STL查找的水题,谁曾想被卡卡时间了
cin输入被卡了,map+scanf+printf==AC
map+cin+cout==T;可能数据太大了
map内置数据结构为红黑树查找和储存效率O(logn);
unordered_map内置数据结构为哈希表(散列表);哈希函数选的好的话,散列地址不大量冲突的话,储存效率O(1),也就是常量级;查找应该也是O(1);那这效率就很可观了(这好的数据结构不是蒻羁想到,是我在洛谷上从dalao那问来的)
unordered_map使用是要注意几点(一个不注意程序就崩了)
(1)要加头文件,一种奇怪的写法,暂时不懂
#include <tr1/unordered_map>
using std::tr1::unordered_map;
(2)要写一个哈希函数,用来应对散列地址冲突,哈希函数构造的好,代码效率直接起飞,反之直接蹦;我的函数哈希函数随便写的,居然没蹦?

两个数据结构各有千秋,就这一题而言unordered_map更快

map(AC)

#include<iostream>
#include<algorithm>
#include<map>
#include<cstdio>
using namespace std;
const int N=1e5+10;
int next1[4][2]={1,0,0,1,0,-1,-1,0};
struct st{
    int x,y;
    int num;
    st()
    {
        num=0;
    }
};
class mp{//map排序规则(没这个会报错) 
    public:
    bool operator()(const st &a,const st &b)const
    {
        return (a.x<b.x)||
        (a.x==b.x&&a.y<b.y)||(false);
    } 
};
/*
4
1 1
0 1
1 0
1 2
*/
int main()
{
    int n;
    int x,y;
    int nx,ny,num=0;
    st t;
    st s[N];
    map<st,int,mp>m;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d%d",&x,&y);
        s[i].x=x;
        s[i].y=y;
        t.x=x;
        t.y=y;
        m.insert(make_pair(t,1));
    }
    for(int i=0;i<n;i++)
    {
        x=s[i].x;
        y=s[i].y;
        nx=ny=0;
        num=0;
        for(int j=0;j<4;j++)
        {
            nx=next1[j][0]+x;
            ny=next1[j][1]+y;
            t.x=nx;
            t.y=ny;
            if(m.find(t)!=m.end())
            {
                num++;  
            }   
        }
        printf("%d\n",num);
    }
    return 0;
}

unordered_map(AC)

#include<iostream>
#include<cstdio>
#include<tr1/unordered_map>
using std::tr1::unordered_map;
using namespace std;
const int N=1e+5+10;
int next1[4][2]={1,0,0,1,0,-1,-1,0};
class st{
	public:
	int x,y;
	int num;
	st(){num=0;}
}s[N];
class hash_v{//哈希函数 
	public:
		size_t operator()(const pair<int,int>&p)const
		{//这是我自己随便写的;
		//通过函数给key一个值,然后地址储存 
			return p.first*111+p.second;
		}
};
struct pair_hash {//哈希函数 
//这是百度的,也能用,但是不太理解 
	template<class t1, class t2>
	std::size_t operator() (const std::pair<t1, t2>& p) const {
		return std::tr1::hash<t1>{}(p.first)^std::tr1::hash<t2>{}(p.second);
	}
};
int read()//输入加速挂 
{
    char ch=' ';
    int ans=0;
    while(ch<'0' || ch>'9')
        ch=getchar();
    while(ch<='9' && ch>='0')
    {
        ans=ans*10+ch-'0';
        ch=getchar();
    }
    return ans;
}
void out(int a)//输出加速挂 
{
    if(a > 9)
    {
        out(a/10);
    }
    putchar(a%10 + '0');
}
/*
4
1 1
0 1
1 0
1 2
*/
int main()
{
	unordered_map<pair<int,int>,int,hash_v>m;//创建一个对象 
	int n;
	int x,y;
	int nx,ny,num=0;
	pair<int,int>t;
	n=read();
	for(int i=0; i<n; i++) { 
		x=read();
		y=read();
		s[i].x=x;
		s[i].y=y;
		t.first=x;
		t.second=y;
		m.insert(make_pair(t,true));//存入哈希表 
	}
	for(int i=0; i<n; i++)
	{
		x=s[i].x;
		y=s[i].y;
		nx=ny=0;
		num=0;
		for(int j=0; j<4; j++)//该点的四个方向 
		{
			nx=next1[j][0]+x;
			ny=next1[j][1]+y;
			t.first=nx;//t为一个点 
			t.second=ny;
			if(m.find(t)!=m.end())//散列查找 
			{
				num++;
			}
		}
		s[i].num=num;//该点相邻点计数 
	}
	for(int i=0; i<n; i++)
	{//输出 
	//printf输出也行,cout输出会超时 
		out(s[i].num);
		printf("\n");
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值