P4305 不重复的数字题解
一、STL+scanf大法
#include <bits/stdc++.h>
using namespace std;
int t;//数据组数
int n;//表示给定的数
unordered_map<int, int> _map;
int x;
int main() {
scanf("%d",&t);
while (t--) {
scanf("%d",&n);
_map.clear();
for (int i = 1; i <= n; i++) {
scanf("%d",&x);
if (!_map[x]) {
printf("%d ", x);
_map[x] = 1;
}
}
printf("\n");
}
return 0;
}
注意:不能用cin,cout,否则后4个测试点TLE!只好使用scanf,printf可以正常通过!
如果强行要使用cin,cout,需要这样:
#include <bits/stdc++.h>
using namespace std;
int t;//数据组数
int n;//表示给定的数
unordered_map<int, int> _map;
int x;
int main() {
ios::sync_with_stdio(false);
cin.tie(0); //注意使用cin.tie(0);
cin >> t;
while (t--) {
cin >> n;
_map.clear();
for (int i = 1; i <= n; i++) {
cin >> x;
if (!_map[x]) {
cout<<x<<" ";
_map[x] = 1;
}
}
cout << endl;
}
return 0;
}
二、HASH表模板
#include <bits/stdc++.h>
using namespace std;
int t;//数据组数
int n;//表示给定的数
//哈希表 模板题
/**
测试用例:
2
11
1 2 18 3 3 19 2 3 6 5 4
6
1 2 3 4 5 6
参考答案:
1 2 18 3 19 6 5 4
1 2 3 4 5 6
*/
const int MOD = 1000003;
vector<int> linker[MOD + 10];//这相当于一个二维动态数组,一维是固定的,二维是动态的.一维对应着HASH后的值,二维是一个链表
int x; //每次读入的数字
//检查是不是出现过
bool insert(int val) {
int pos = (val % MOD + MOD) % MOD;//可以处理负数!如此处理,负数也要散列到正数的范围内!
for (int i = 0; i < linker[pos].size(); i++)
if (linker[pos][i] == val) return true;
//没有存在过,加进去
linker[pos].push_back(val);
return false;
}
int main() {
//不用scanf,只使用cin,会TLE掉后4个点
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
//初始化
memset(linker, 0, sizeof linker);
//一般读入,一边判断是否出现过
for (int i = 1; i <= n; i++) {
scanf("%d", &x);
if (!insert(x)) printf("%d ", x);
}
printf("\n");
}
return 0;
}
总结如下:
1、二维HASH表,一维代表HASH后的值,二维代表HASH中相同的情况下,有哪些数据,是一个动态的数组。通过遍历的方法查找所有的相同HASH值数据。
2、模板,没有其它需要说的了。