您的位置:首页 > 其它

HDU 4941 Magical Forest (Hash)

2014-08-18 20:35 441 查看
这个题比赛的时候是乱搞的,比赛结束之后学长说是映射+hash才恍然大悟。因此决定好好学一下hash。

题意:

  M*N的格子,里面有一些格子里面有一个值。

  有三种操作:

    1.交换两行的值。

    2.交换两列的值。

    3.询问某个格子的值。

  保证,交换的时候要么两行都有值,要么两行都为空。

思路:

  其实交换两行或者两列的话,相当于把那两行的对应下标交换一下。因此我们可以想到,对行标和列表建立一个索引,交换的时候,我们只需要交换一下索引。

  因为行和列比较多,所以我们不能直接存整个矩阵,即使离散化也不可以,所以这里我们需要用到hash。(Map也可以)。

代码:

  

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <string>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <functional>
#include <time.h>

using namespace std;

typedef __int64 ll;

const int INF = 1<<30;
const int MAXN = (int) 1e5+50;
const ll HASH = (ll) (1e6)+3;

struct node {
int x, y, e;
}a[MAXN];

int hash_table[HASH], next[MAXN];

int d_x[MAXN], d_y[MAXN], len_x, len_y;
int xx[MAXN], yy[MAXN];
int n;
ll mx, my;

inline void add(int x, int y, int k) {
int id = ((ll)x*n+y)%HASH;
next[k] = hash_table[id];
hash_table[id] = k;
}

inline int find(int x, int y) {
int id = ((ll)x*n+y)%HASH;
int p;
for (p = hash_table[id]; p!=-1; p = next[p])
if (a[p].x==x&&a[p].y==y)
return a[p].e;
return 0;
}

void solve() {
memset(hash_table, -1, sizeof(hash_table));
scanf("%d%d%d", &mx, &my, &n);
for (int i = 0; i < n; i++) {
scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].e);
d_x[i] = a[i].x;
d_y[i] = a[i].y;
xx[i] = yy[i] = i;
}
sort(d_x, d_x+n);
len_x = unique(d_x, d_x+n) - d_x;
sort(d_y, d_y+n);
len_y = unique(d_y, d_y+n) - d_y;
for (int i = 0; i < n; i++) {
a[i].x = lower_bound(d_x, d_x+len_x, a[i].x)-d_x;
a[i].y = lower_bound(d_y, d_y+len_y, a[i].y)-d_y;
add(a[i].x, a[i].y, i);
}

int Q, o, x, y;
int rx, ry;
scanf("%d", &Q);
while (Q--) {
scanf("%d%d%d", &o, &x, &y);
if (o==1) {
rx = lower_bound(d_x, d_x+len_x, x) - d_x;
ry = lower_bound(d_x, d_x+len_x, y) - d_x;
if (x==d_x[rx]&&y==d_x[ry]) swap(xx[rx], xx[ry]);
} else if (o==2) {
rx = lower_bound(d_y, d_y+len_y, x) - d_y;
ry = lower_bound(d_y, d_y+len_y, y) - d_y;
if (x==d_y[rx]&&y==d_y[ry]) swap(yy[rx], yy[ry]);
} else {
rx = lower_bound(d_x, d_x+len_x, x) - d_x;
ry = lower_bound(d_y, d_y+len_y, y) - d_y;
if (x==d_x[rx]&&y==d_y[ry]) printf("%d\n", find(xx[rx], yy[ry]));
else puts("-1");
}
}
}

int main() {
#ifdef Phantom01
freopen("HDU4941.in", "r", stdin);
freopen("my4941.txt", "w", stdout);
#endif //Phantom01

int T;
scanf("%d", &T);
for (int i = 1; i <= T; i++) {
printf("Case #%d:\n", i);
solve();
}

return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: