PAT 九章 哈希表 1-8 自用

九哈希表1 1532. 找硬币 PAT甲级真题1048

1532. 找硬币

伊娃喜欢从整个宇宙中收集硬币。

有一天,她去了一家宇宙购物中心购物,结账时可以使用各种硬币付款。

但是,有一个特殊的付款要求:每张帐单,她只能使用恰好两个硬币来准确的支付消费金额。

给定她拥有的所有硬币的面额,请你帮她确定对于给定的金额,她是否可以找到两个硬币来支付。

输入格式
第一行包含两个整数 N和 M,分别表示硬币数量以及需要支付的金额。

第二行包含 N个整数,表示每个硬币的面额。

输出格式
输出一行,包含两个整数 V1, V2,表示所选的两个硬币的面额,使得 V1≤V2并且 V1 + V2 = M。

如果答案不唯一,则输出 V1最小的解。

如果无解,则输出 No Solution。

数据范围
1≤N≤105,
1≤M≤1000


输入样例1:

8 15
1 2 8 7 2 4 11 15

输出样例1:

4 11

输入样例2:

7 14
1 8 7 2 4 11 15

输出样例2:

No Solution

Eva loves to collect coins from all over the universe, including some other planets like Mars. One day she visited a universal shopping mall which could accept all kinds of coins as payments. However, there was a special requirement of the payment: for each bill, she could only use exactly two coins to pay the exact amount. Since she has as many as 105 coins with her, she definitely needs your help. You are supposed to tell her, for any given amount of money, whether or not she can find two coins to pay for it.

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 positive numbers: N (<=105, the total number of coins) and M(<=103, the amount of money Eva has to pay). The second line contains N face values of the coins, which are all positive numbers no more than 500. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print in one line the two face values V1 and V2 (separated by a space) such that V1 + V2 = M and V1 <= V2. If such a solution is not unique, output the one with the smallest V1. If there is no solution, output "No Solution" instead.

Sample Input 1:

8 15
1 2 8 7 2 4 11 15

Sample Output 1:

4 11

Sample Input 2:

7 14
1 8 7 2 4 11 15

Sample Output 2:

No Solution

题目大意:给出n个正整数和一个正整数m,问n个数字中是否存在一对数字a和b(a <= b),使a+b=m成立。如果有多个,输出a最小的那一对。

分析:建立数组a保存每个数字出现的次数,然后判断输出

我:yxc:

遍历全部数字,

遍历到1,哈希表里有数组能和1组成15吗?没有,1放入哈希表, 

遍历到2,哈希表里有数组能和2组成15吗?没有,2放入哈希表, 

遍历到8,哈希表里有数组能和8组成15吗?没有,8放入哈希表, 

遍历到7,哈希表里有数组能和7组成15吗?有,记录下7,8,,7放入哈希表, 

遍历到2,哈希表里有数组能和2组成15吗?没有,2放入哈希表, 

遍历到4,哈希表里有数组能和4组成15吗?没有,4放入哈希表, 

遍历到11,哈希表里有数组能和11组成15吗?有,记录下11和4,11放入哈希表, 

遍历到15,哈希表里有数组能和15组成15吗?没有,15放入哈希表, 

//1532. 找硬币
//
//伊娃喜欢从整个宇宙中收集硬币。
//
//有一天,她去了一家宇宙购物中心购物,结账时可以使用各种硬币付款。
//
//但是,有一个特殊的付款要求:每张帐单,她只能使用恰好两个硬币来准确的支付消费金额。
//
//给定她拥有的所有硬币的面额,请你帮她确定对于给定的金额,她是否可以找到两个硬币来支付。
//
//输入格式
//第一行包含两个整数 N和 M,分别表示硬币数量以及需要支付的金额。
//
//第二行包含 N个整数,表示每个硬币的面额。
//
//输出格式
//输出一行,包含两个整数 V1, V2,表示所选的两个硬币的面额,使得 V1≤V2并且 V1 + V2 = M。
//
//如果答案不唯一,则输出 V1最小的解。
//
//如果无解,则输出 No Solution。
//
//数据范围
//1≤N≤105,
//1≤M≤1000
//输入样例1:
//8 15
//1 2 8 7 2 4 11 15
//输出样例1:
//4 11
//
//输入样例2:
//7 14
//1 8 7 2 4 11 15
//输出样例2:
//No Solution

#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include <unordered_set>
#include <set>
#include <unordered_map>
#include<algorithm>
#include<deque>
#include <math.h>
#include<cstdio>
using namespace std;

int n, m;//分别表示硬币数量以及需要支付的金额。
class Solution {
public:
	void func() {
        cin >> n >> m;//n=8个硬币,要凑出金额m=15

        unordered_set<int> S;//去重复,无须,哈希表
        int v1 = 1e9, v2;//1e9=10的9次方
        for (int i = 0; i < n; i++){//遍历8个硬币数额
            int x;
            cin >> x;
            int y = m - x;
            //已知x硬币的数额,如果找到了能凑出15的y硬币
            if (S.count(y)){
                S.insert(x);
                if (x > y) swap(x, y);//小的在前
                if (x < v1) v1 = x, v2 = y;//如果答案不唯一,则输出 V1最小的解。
            }
            //如果没找到则将硬币放入哈希池
            else S.insert(x);
        }
        if (v1 == 1e9) puts("No Solution");
        else cout << v1 << ' ' << v2 << endl;
	}
};

class Solution2 {
public:
	void func() {

	}
};

int main() {
	Solution s;
	s.func();
	return 0;
}

九哈希表2 1549. 集合相似度  PAT甲级真题1063

1549. 集合相似度

//给定两个整数集合,两个集合的相似度定义为 Nc / Nt×100 %,
//其中 Nc是两个集合中都存在的不同整数的数量,Nt是两个集合中不同整数的数量。
//
//现在,请你计算给定集合的相似度。
//
//输入格式
//第一行包含整数 N,表示集合数量。
//
//接下来 N行,每行包含一个集合的信息,首先包含一个整数 M,
//表示集合中的数的个数,然后包含 M个整数,表示集合中的每个元素。
//
//再一行,包含整数 K,表示询问次数。
//
//接下来 K行,每行包含一组询问,包括两个整数 a和 b,
//表示询问集合 a和集合 b的相似度。
//
//所有集合的编号为 1∼N。
//
//输出格式
//每行输出一个询问的结果,保留一位小数。
//
//输出答案与标准答案的绝对误差不超过 0.1
//即视为正确。
//
//数据范围
//1≤N≤50,
//1≤M≤10000,
//1≤K≤2000,
//集合中的元素取值均在[0, 109]范围内。
 

输入样例:

3
3 99 87 101
4 87 101 5 87
7 99 101 18 5 135 18 99
2
1 2
1 3

输出样例:

50.0%
33.3%

Given two sets of integers, the similarity of the sets is defined to be Nc/Nt*100%, where Nc is the number of distinct common numbers shared by the two sets, and Nt is the total number of distinct numbers in the two sets. Your job is to calculate the similarity of any given pair of sets.

Input Specification:

Each input file contains one test case. Each case first gives a positive integer N (<=50) which is the total number of sets. Then N lines follow, each gives a set with a positive M (<=104) and followed by M integers in the range [0, 109]. After the input of sets, a positive integer K (<=2000) is given, followed by K lines of queries. Each query gives a pair of set numbers (the sets are numbered from 1 to N). All the numbers in a line are separated by a space.

Output Specification:

For each query, print in one line the similarity of the sets, in the percentage form accurate up to 1 decimal place.

Sample Input:

3
3 99 87 101
4 87 101 5 87
7 99 101 18 5 135 18 99
2
1 2
1 3

Sample Output:

50.0%
33.3%

题目大意:给定两个整数集合,它们的相似度定义为:Nc/Nt*100%。其中Nc是两个集合都有的不相等整数的个数,Nt是两个集合一共有的不相等整数的个数。你的任务就是计算任意一对给定集合的相似度
nc是两个集合的公共元素个数,nt是两个集合的所有包含的元素个数(其中元素个数表示各个元素之间互不相同)

分析:因为给出的集合里面含有重复的元素,而计算nc和nt不需要考虑两个集合里面是否分别有重复的元素,所以可以直接使用set存储每一个集合,然后把set放进一个数组里面存储。当需要计算集合a和集合b的相似度nc和nt的时候,遍历集合a中的每一个元素,寻找集合b中是否有该元素,如果有,说明是两个人公共的集合元素,则nc++,否则nt++(nt的初值为b集合里面本有的元素)
 

//1549. 集合相似度
//
//给定两个整数集合,两个集合的相似度定义为 Nc / Nt×100 %,
//其中 Nc是两个集合中都存在的不同整数的数量,Nt是两个集合中不同整数的数量。
//
//现在,请你计算给定集合的相似度。
//
//输入格式
//第一行包含整数 N,表示集合数量。
//
//接下来 N行,每行包含一个集合的信息,首先包含一个整数 M,
//表示集合中的数的个数,然后包含 M个整数,表示集合中的每个元素。
//
//再一行,包含整数 K,表示询问次数。
//
//接下来 K行,每行包含一组询问,包括两个整数 a和 b,
//表示询问集合 a和集合 b的相似度。
//
//所有集合的编号为 1∼N。
//
//输出格式
//每行输出一个询问的结果,保留一位小数。
//
//输出答案与标准答案的绝对误差不超过 0.1
//即视为正确。
//
//数据范围
//1≤N≤50,
//1≤M≤10000,
//1≤K≤2000,
//集合中的元素取值均在[0, 109]范围内。
//
//输入样例:
//3
//3 99 87 101
//4 87 101 5 87
//7 99 101 18 5 135 18 99
//2
//1 2
//1 3
//输出样例:
//50.0 %
//33.3 %


#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include <unordered_set>
#include <set>
#include <unordered_map>
#include<algorithm>
#include<deque>
#include <math.h>
#include<cstdio>
using namespace std;
const int N = 55;

//yxc:
//先将集合a,b放进unordered_set<int> 里去重复,然后Nc就是a交b,取交集的数,Nt就是取并集
//求Nc:遍历集合a中元素,比如遍历到x,若集合b也有x,即S.count(x)==1,则cout++,最后cout就是Nc
//求Nt法一:a.size()+b.size()-Nc即可(韦恩图)
//求Nt法二:比如a是1,2,3;b是2,3,4,count初始值是a.size()=3,遍历集合a,若有不同元素则cout++即可
int n;
//去重复,无序//这是哈希表的数组
//第一个集合的数存放在S[1]中,分别是S[1][0],s[1][1],...第二个集合的数存放在S[2]中
unordered_set<int> S[N];
class Solution {
public:
	void func() {
        scanf("%d", &n);//n个集合

        //输入集合
        for (int i = 1; i <= n; i++){
            int m;//输入当前集合有几个数,m个
            scanf("%d", &m);
            while (m--){
                int x;
                scanf("%d", &x);//输入当前集合的m个数
                S[i].insert(x);//
            }
        }

        //输入查询
        int k;
        scanf("%d", &k);//样例中k=2
        while (k--){
            int a, b;//查询a,b号集合
            scanf("%d%d", &a, &b);
            int Nc = 0;//Nc是两个集合中都存在的不同整数的数量

            //遍历a号集合
            for (auto x : S[a]) {
                Nc += S[b].count(x);
            }
            int Nt = S[a].size() + S[b].size() - Nc;
            printf("%.1lf%%\n", (double)Nc / Nt * 100);
        }
	}
};

class Solution2 {
public:
	void func() {

	}
};

int main() {
	Solution s;
	s.func();
	return 0;
}

九哈希表3 1610. 朋友数 PAT甲级真题1120

1610. 朋友数

如果两个整数各位数字的和是一样的,则被称为是“朋友数”,而那个公共的和就是它们的“朋友证号”。

例如 123123 和 5151 就是朋友数,因为 1+2+3=5+1=61+2+3=5+1=6,而 66 就是它们的朋友证号。

给定一些整数,要求你统计一下它们中有多少个不同的朋友证号。

输入格式

输入第一行给出正整数 N。

随后一行给出 N 个正整数,数字间以空格分隔。

输出格式

首先第一行输出给定数字中不同的朋友证号的个数;

随后一行按递增顺序输出这些朋友证号,数字间隔一个空格,且行末不得有多余空格。

数据范围

1≤N≤10000,
给定正整数均不超过 10000。

输入样例:

8
123 899 51 998 27 33 36 12

输出样例:

4
3 6 9 26

1120. Friend Numbers (20)

Two integers are called “friend numbers” if they share the same sum of their digits, and the sum is their “friend ID”. For example, 123 and 51 are friend numbers since 1+2+3 = 5+1 = 6, and 6 is their friend ID. Given some numbers, you are supposed to count the number of different friend ID’s among them. Note: a number is considered a friend of itself.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N. Then N positive integers are given in the next line, separated by spaces. All the numbers are less than 10^4.

Output Specification:

For each case, print in the first line the number of different frind ID’s among the given integers. Then in the second line, output the friend ID’s in increasing order. The numbers must be separated by exactly one space and there must be no extra space at the end of the line.

Sample Input:
8
123 899 51 998 27 33 36 12
Sample Output:
4
3 6 9 26

分析:在接收输入数据的时候就把该数字的每一位相加,并把结果插入一个set集合中。因为set是有序的、不重复的,所以set的size值就是输出的个数,set中的每一个数字即所有答案的数字序列
 

//1610. 朋友数
//
//如果两个整数各位数字的和是一样的,则被称为是“朋友数”,而那个公共的和就是它们的“朋友证号”。
//
//例如 123和 51就是朋友数,因为 1 + 2 + 3 = 5 + 1 = 6,而 6就是它们的朋友证号。
//
//给定一些整数,要求你统计一下它们中有多少个不同的朋友证号。
//
//输入格式
//输入第一行给出正整数 N。
//
//随后一行给出 N个正整数,数字间以空格分隔。
//
//输出格式
//首先第一行输出给定数字中不同的朋友证号的个数;
//
//随后一行按递增顺序输出这些朋友证号,数字间隔一个空格,且行末不得有多余空格。
//
//数据范围
//1≤N≤10000,
//给定正整数均不超过 10000。
//
//输入样例:
//8
//123 899 51 998 27 33 36 12
//
//输出样例:
//4
//3 6 9 26


#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include <unordered_set>
#include <set>
#include <unordered_map>
#include<algorithm>
#include<deque>
#include <math.h>
#include<cstdio>
using namespace std;

//yxc
class Solution {
public:
	void func() {
        int n;//n个数字
        cin >> n;

        set<int> S;
        while (n--){
            int x;
            cin >> x;
            int s = 0;
            while (x != 0) s += x % 10, x /= 10;//获得朋友数
            S.insert(s);//set中插入朋友数
        }

        cout << S.size() << endl;

        //输出,注意pat末尾无空格
        bool is_first = true;
        for (auto x : S){
            if (is_first) is_first = false;
            else cout << ' ';
            cout << x;
        }
	}
};

//柳:充分利用了set的去重复,有序
class Solution2 {
public:
    //获得朋友数:每个位的数字 之和
    int getFriendNum(int num) {
        int sum = 0;
        while (num != 0) {
            sum += num % 10;
            num /= 10;
        }
        return sum;
    }
	void func() {
        set<int> s;//去重复,且有序
        int n, num;
        scanf("%d", &n);//有n数字
        for (int i = 0; i < n; i++) {
            scanf("%d", &num);//输入每个数字
            s.insert(getFriendNum(num));//set中插入每个数字朋友数
        }
        printf("%d\n", s.size());//输出有几个朋友数
        for (auto it = s.begin(); it != s.end(); it++) {//遍历set就是答案
            if (it != s.begin()) printf(" ");
            printf("%d", *it);
        }
	}
};

int main() {
	Solution2 s;
	s.func();
	return 0;
}

九哈希表4 1637. 漏掉的数字 PAT甲级真题1144 

1637. 漏掉的数字

给定 N个整数,请你找出最小的不在给定整数列表中的正整数。

输入格式

第一行包含整数 N。

第二行包含 N 个整数,整数之间用空格隔开,所有数字都在 int 范围内。

输出格式

输出不在给定整数列表中的最小正整数。

数据范围

1≤N≤105

输入样例:

10
5 -25 9 6 1 3 4 2 5 17

输出样例:

7

Given N integers, you are supposed to find the smallest positive integer that is NOT in the given list.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (<= 105). Then N integers are given in the next line, separated by spaces. All the numbers are in the range of int.

Output Specification:

Print in a line the smallest positive integer that is missing from the input list.

Sample Input:

10
5 -25 9 6 1 3 4 2 5 17

Sample Output:

7

题目大意:给n个数字,找到不在这个数字列表里面的最小的正整数

分析:将每个数字出现的次数存储在map里面,num从1开始,如果m[num] == 0说明不存在,则输出这个num~
 

//1637. 漏掉的数字
//
//给定 N个整数,请你找出最小的不在给定整数列表中的正整数。
//
//输入格式
//第一行包含整数 N。
//
//第二行包含 N个整数,整数之间用空格隔开,所有数字都在 int 范围内。
//
//输出格式
//输出不在给定整数列表中的最小正整数。
//
//数据范围
//1≤N≤10^5
//输入样例:
//10
//5 - 25 9 6 1 3 4 2 5 17
//输出样例:
//7

#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include <unordered_set>
#include <set>
#include <unordered_map>
#include<algorithm>
#include<deque>
#include <math.h>
#include<cstdio>
using namespace std;

//太简单 过
//输入放进set里,遍历从1开始的整数,哪个整数没有就输出就完了
class Solution {
public:
	set<int> s;
	void func() {
		int n;
		int x;
		cin >> n;
		for (int i = 0; i < n; i++) {
			cin >> x;
			s.insert(x);
		}
		for (int i = 1; i <= 1000000; i++) {
			if (s.count(i) == 0) {
				cout << i;
				break;
			}
		}
	}
};

//yxc
class Solution2 {
public:
	void func() {
		int n;
		cin >> n;

		unordered_set<int> S;
		while (n--)
		{
			int x;
			cin >> x;
			S.insert(x);
		}

		int res = 1;
		while (S.count(res)) res++;

		cout << res << endl;
	}
};

int main() {
	Solution s;
	s.func();
	return 0;
}

九哈希表5 1642. 危险品装箱 PAT甲级真题1149

1642. 危险品装箱

集装箱运输货物时,我们必须特别小心,不能把不相容的货物装在一只箱子里。

比如氧化剂绝对不能跟易燃液体同箱,否则很容易造成爆炸。

本题给定一张不相容物品的清单,需要你检查每一张集装箱货品清单,判断它们是否能装在同一只箱子里。

输入格式

输入第一行给出两个正整数:N 是成对的不相容物品的对数;M 是集装箱货品清单的单数。

随后数据分两大块给出。第一块有 N行,每行给出一对不相容的物品。

第二块有 M 行,每行给出一箱货物的清单,格式如下:

K G[1] G[2] ... G[K]

其中 K 是物品件数,G[i] 是物品的编号。

简单起见,每件物品用一个 55 位数的编号代表。

两个数字之间用空格分隔。

输出格式

对每箱货物清单,判断是否可以安全运输。

如果没有不相容物品,则在一行中输出 Yes,否则输出 No

数据范围

1≤N≤10^4,
1≤M≤100,
1≤K≤1000

输入样例:

6 3
20001 20002
20003 20004
20005 20006
20003 20001
20005 20004
20004 20006
4 00001 20004 00002 20003
5 98823 20002 20003 20006 10010
3 12345 67890 23333

输出样例:

No
Yes
Yes

When shipping goods with containers, we have to be careful not to pack some incompatible goods into the same container, or we might get ourselves in serious trouble. For example, oxidizing agent (氧化剂) must not be packed with flammable liquid (易燃液体), or it can cause explosion.

Now you are given a long list of incompatible goods, and several lists of goods to be shipped. You are supposed to tell if all the goods in a list can be packed into the same container.

Input Specification:

Each input file contains one test case. For each case, the first line gives two positive integers: N (≤10​4), the number of pairs of incompatible goods, and M (≤100), the number of lists of goods to be shipped.

Then two blocks follow. The first block contains N pairs of incompatible goods, each pair occupies a line; and the second one contains M lists of goods to be shipped, each list occupies a line in the following format:

K G[1] G[2] … G[K]
where K (≤1,000) is the number of goods and G[i]’s are the IDs of the goods. To make it simple, each good is represented by a 5-digit ID number. All the numbers in a line are separated by spaces.

Output Specification:

For each shipping list, print in a line Yes if there are no incompatible goods in the list, or No if not.

Sample Input:

6 3
20001 20002
20003 20004
20005 20006
20003 20001
20005 20004
20004 20006
4 00001 20004 00002 20003
5 98823 20002 20003 20006 10010
3 12345 67890 23333

Sample Output:

No
Yes
Yes

题目大意:集装箱运输货物时,我们必须特别小心,不能把不相容的货物装在一只箱子里。比如氧化剂绝对不能跟易燃液体同箱,否则很容易造成爆炸。给定一张不相容物品的清单,需要你检查每一张集装箱货品清单,判断它们是否能装在同一只箱子里。对每箱货物清单,判断是否可以安全运输。如果没有不相容物品,则在一行中输出 Yes,否则输出 No~

分析:用map存储每一个货物的所有不兼容货物~在判断给出的一堆货物是否是相容的时候,判断任一货物的不兼容货物是否在这堆货物中~如果存在不兼容的货物,则这堆货物不能相容~如果遍历完所有的货物,都找不到不兼容的两个货物,则这堆货物就是兼容的~
 

//1642. 危险品装箱
//
//集装箱运输货物时,我们必须特别小心,不能把不相容的货物装在一只箱子里。
//
//比如氧化剂绝对不能跟易燃液体同箱,否则很容易造成爆炸。
//
//本题给定一张不相容物品的清单,需要你检查每一张集装箱货品清单,
//判断它们是否能装在 同一只箱子 里。
//
//输入格式
//输入第一行给出两个正整数:N是成对的 不相容 物品的对数;
//M是 集装箱货品清单 的单数。
//
//随后数据分两大块给出。第一块有 N行,每行给出一对 不相容 的物品。
//
//第二块有M行,每行给出一箱货物的清单,格式如下:
//
//K G[1] G[2] ... G[K]
//其中 K 是物品件数,G[i]是物品的编号。
//
//简单起见,每件物品用一个5位数的编号代表。
//
//两个数字之间用空格分隔。
//
//输出格式
//对每箱货物清单,判断是否可以安全运输。
//
//如果没有不相容物品,则在一行中输出 Yes,否则输出 No。
//
//数据范围
//1≤N≤104,
//1≤M≤100,
//1≤K≤1000
//输入样例:
//6 3
//20001 20002
//20003 20004
//20005 20006
//20003 20001
//20005 20004
//20004 20006
//4 00001 20004 00002 20003
//5 98823 20002 20003 20006 10010
//3 12345 67890 23333
//输出样例:
//No
//Yes
//Yes


#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include <unordered_set>
#include <set>
#include <unordered_map>
#include<algorithm>
#include<deque>
#include <math.h>
#include<cstdio>
using namespace std;
const int N = 10010;

//我:;类似十一章模拟题 1614单身狗的思路,简单题
//将不相容的数字,放入incompatible结构体数组中,待查询数字,放入unordered_set<int> s中
//遍历incompatible结构体数组,看是否能在unordered_set<int> s中找到不相容的俩数字
//即if (s.count(a) != 0 && s.count(b) != 0),找到就break,输出No,没找到就Yes,完!
struct incompatible {
	int a;
	int b;
}I[N];
class Solution {
public:
	void func() {
		int n = 0;//有几对不相容数据
		int	m = 0;//查询次数
		
		cin >> n >> m;
		for (int i = 0; i < n; i++) {
			cin >> I[i].a >> I[i].b;//不相容数据放入结构体中
		}

		//m次查询
		for (int i = 0; i < m; i++) {
			int k;//每次查多少数
			bool f = true;//默认是合格,没有不相容
			cin >> k;
			unordered_set<int> s;//用于存放查询的数字
			while (k--) {
				int t;
				cin >> t;
				s.insert(t);
			}
			for (int j = 0; j < n; j++) {//遍历不相容结构体数组
				int a = I[j].a;
				int b = I[j].b;
				if (s.count(a) != 0 && s.count(b) != 0) {//判断是否有不相容
					f = false;//不可以安全运输
					break;
				}
			}
			if (f==false) {//如果不可以安全运输
				cout << "No" << endl;
			}
			else {
				cout << "Yes" << endl;
			}
		}
	}
};

//yxc:用什么方法 要考虑数据范围//和我方法思路一样,不看了。
int n, m;
int a[N], b[N];
class Solution2 {
public:
	void func() {
		scanf("%d%d", &n, &m);
		for (int i = 0; i < n; i++) scanf("%d%d", &a[i], &b[i]);//读入n对儿物品

		while (m--){//m个询问
			int k;//每个询问清单里有k个物品
			scanf("%d", &k);
			unordered_set<int> S;//存放询问的物品
			while (k--){//读入k个物品
				int x;
				scanf("%d", &x);
				S.insert(x);
			}

			bool success = true;
			for (int i = 0; i < n; i++)
				if (S.count(a[i]) && S.count(b[i]))
				{
					success = false;
					break;
				}

			if (success) puts("Yes");
			else puts("No");
		}
	}
};

int main() {
	Solution s;
	s.func();
	return 0;
}

九哈希表6 1564. 哈希 PAT甲级真题1078

1564. 哈希

将一个由若干个不同正整数构成的整数序列插入到一个哈希表中,然后输出输入数字的位置。

哈希函数定义为 H(key) = key % TSize,其中 TSize是哈希表的最大大小。

利用只具有 正增量的二次探测法 来解决冲突。

注意,哈希表的大小最好是素数,如果用户给出的最大大小不是素数,
则必须将表大小重新定义为大于用户给出的大小的最小素数。

输入格式
第一行包含两个整数 MSize和 N,分别表示用户定义的 表的大小 以及 输入数字的数量。

第二行包含 N个不同的正整数,数字之间用空格隔开。

输出格式
在一行中,输出每个输入数字的相应位置(索引从 0开始),
数字之间用空格隔开,行尾不得有多余空格。

如果无法插入某个数字,则输出 - 。

数据范围
1≤MSize≤104,
1≤N≤MSize,
输入数字均在[1, 105]范围内。

输入样例:

4 4
10 6 4 15

输出样例:

0 1 4 -

The task of this problem is simple: insert a sequence of distinct positive integers into a hash table, and output the positions of the input numbers. The hash function is defined to be "H(key) = key % TSize" where TSize is the maximum size of the hash table. Quadratic probing (with positive increments only) is used to solve the collisions.

Note that the table size is better to be prime. If the maximum size given by the user is not prime, you must re-define the table size to be the smallest prime number which is larger than the size given by the user.

Input Specification:

Each input file contains one test case. For each case, the first line contains two positive numbers: MSize (<=104) and N (<=MSize) which are the user-defined table size and the number of input numbers, respectively. Then N distinct positive integers are given in the next line. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print the corresponding positions (index starts from 0) of the input numbers in one line. All the numbers in a line are separated by a space, and there must be no extra space at the end of the line. In case it is impossible to insert the number, print "-" instead.

Sample Input:

4 4
10 6 4 15

Sample Output:

0 1 4 -

题目大意:给出散列表长和要插入的元素,将这些元素按照读入的顺序插入散列表中,其中散列函数为h(key) = key % TSize,解决冲突采用只向正向增加的二次方探查法。如果题中给出的TSize不是素数,就取第一个比TSize大的素数作为TSize

分析:先解决size是否为素数,不是素数就要重新赋值的问题

然后根据二次方探查法:

如果hashTable里面key % size的下标对应的hashTable为false,说明这个下标没有被使用过,直接输出。否则step步长从1加到size-1,一次次尝试是否能使index = (key + step * step) % size;所对应的位置没有元素,如果都没有找到就输出“-”,否则就输出这个找到的元素的位置~

注意 是(key + step * step) % size 而不是(key % size + step * step) 

//1564. 哈希
//
//将一个由若干个不同正整数构成的整数序列插入到一个哈希表中,然后输出输入数字的位置。
//
//哈希函数定义为 H(key) = key % TSize,其中 TSize是哈希表的最大大小。
//
//利用只具有 正增量的二次探测法 来解决冲突。
//
//注意,哈希表的大小最好是素数,如果用户给出的最大大小不是素数,
//则必须将表大小重新定义为大于用户给出的大小的最小素数。
//
//输入格式
//第一行包含两个整数 MSize和 N,分别表示用户定义的 表的大小 以及 输入数字的数量。
//
//第二行包含 N个不同的正整数,数字之间用空格隔开。
//
//输出格式
//在一行中,输出每个输入数字的相应位置(索引从 0开始),
//数字之间用空格隔开,行尾不得有多余空格。
//
//如果无法插入某个数字,则输出 - 。
//
//数据范围
//1≤MSize≤104,
//1≤N≤MSize,
//输入数字均在[1, 105]范围内。
//
//输入样例:
//4 4
//10 6 4 15
//输出样例:
//0 1 4 -


#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include <unordered_set>
#include <set>
#include <unordered_map>
#include<algorithm>
#include<deque>
#include <math.h>
#include<cstdio>
using namespace std;
const int N = 10010;

//yxc:模拟开放定址法,取质数s作为哈希表大小,插入的数字都要模s求出下标,如果该下标有其他数字占了,
//就平方系数1.4.9.16.25地往前跳,超出s了就%s,
int s;//哈希表长度
int n;//输入数字个数
int h[N];//哈希表
class Solution {
public:
	bool is_prime(int x) {
		if (x == 1) return false;//1不是质数

		for (int i = 2; i * i <= x; i++){
			if (x % i == 0){
				return false;//2到根号x 范围内,有数字能被x整除,x就不是质数
			}
		}
		return true;
	}
	//开放寻址法
	int find(int x) {
		int t = x % s;//t是哈希值:x本应在的下标

		//遍历哈希表长度s
		for (int k = 0; k < s; k++){
			int i = (t + k * k) % s;//开放寻址法是平方滴1,4,9,16,25滴往前跳
			if (!h[i]) return i;//如果h[i]==0,这位置没被用过,范围下标i
		}

		return -1;//遍历完整个哈希表发现都没位置可以插入,则返回-1 
	}
	void func() {
		cin >> s >> n;//哈希表大小和输入数字的个数

		while (!is_prime(s)) s++;//如果不是质数,哈希表大小++

		//输入n个不同的数字
		for (int i = 0; i < n; i++){
			int x;
			cin >> x;//存入插入的数字
			int t = find(x);//t是x要插入的下标位置(find是开放寻址法)

			if (t == -1) printf("-");//没找到能插入的下标位置,则输出-
			else{
				h[t] = x;//将x插入哈希表h中,下标是t
				printf("%d", t);//输出下标t
			}
			//pat末尾输出无空格
			if (i != n - 1) printf(" ");
		}
	}
};

class Solution2 {
public:
	
	void func() {

	}
};

int main() {
	Solution s;
	s.func();
	return 0;
}

九哈希表7 1630. 期终成绩 PAT甲级真题1137

1630. 期终成绩

对于在中国大学 MOOC 学习“数据结构”课程的学生,想要获得一张 合格证书,
必须首先获得不少于 200分的在线编程作业分,然后总评获得不少于 60分(满分 100)。

总评成绩的计算公式为 G = (Gmid−term×40 % +Gfinal×60%),
如果 Gmid−term > Gfinal;否则总评 G 就是 Gfinal。

这里 Gmid−term和 Gfinal分别为学生的 期中 和 期末 成绩。

现在的问题是,每次考试都产生一张独立的成绩单。

本题就请你编写程序,把不同的成绩单合为一张。

输入格式
输入在第一行给出 3个整数,分别是 P(做了在线编程作业的学生数)、
M(参加了期中考试的学生数)、N(参加了期末考试的学生数)。

接下来有三块输入。

第一块包含 P个在线编程成绩 Gp;

第二块包含 M个期中考试成绩 Gmid−term;

第三块包含 N个期末考试成绩 Gfinal。

每个成绩占一行,格式为:学生学号 分数。

其中 学生学号 为不超过 20个字符的英文字母和数字;
分数 是非负整数(编程总分最高为 900分,期中和期末的最高分为 100分)。

输出格式
打印出 获得合格证书 的学生名单。

每个学生占一行,格式为:

学生学号 Gp Gmid−term Gfinal G
如果有的成绩不存在(例如某人没参加期中考试),则在相应的位置输出“−1”。

输出顺序为按照总评分数(四舍五入精确到整数)递减。

若有并列,则按学号递增。

题目保证学号没有重复,且至少存在 1个合格的学生。

数据范围
1≤P, M, N≤10000
输入样例:
6 6 7//P(做了在线编程作业的学生数)、M(参加了期中考试的学生数)、N(参加了期末考试的学生数)。
01234 880//第一块包含 P个在线编程成绩 Gp;
a1903 199
ydjh2 200
wehu8 300
dx86w 220
missing 400
ydhfu77 99//第二块包含 M个期中考试成绩 Gmid−term;
wehu8 55
ydjh2 98
dx86w 88
a1903 86
01234 39
ydhfu77 88//第三块包含 N个期末考试成绩 Gfinal。
a1903 66
01234 58
wehu8 84
ydjh2 82
missing 99
dx86w 81
输出样例:
missing 400 - 1 99 99
ydjh2 200 98 82 88
dx86w 220 88 81 84
wehu8 300 55 84 84

For a student taking the online course "Data Structures" on China University MOOC (http://www.icourse163.org/), to be qualified for a certificate, he/she must first obtain no less than 200 points from the online programming assignments, and then receive a final grade no less than 60 out of 100. The final grade is calculated by G = (Gmid-termx 40% + Gfinalx 60%) if Gmid-term > Gfinal, or Gfinal will be taken as the final grade G. Here Gmid-term and Gfinal are the student's scores of the mid-term and the final exams, respectively.

The problem is that different exams have different grading sheets. Your job is to write a program to merge all the grading sheets into one.

Input Specification:

Each input file contains one test case. For each case, the first line gives three positive integers: P , the number of students having done the online programming assignments; M, the number of students on the mid-term list; and N, the number of students on the final exam list. All the numbers are no more than 10,000.

Then three blocks follow. The first block contains P online programming scores Gp’s; the second one contains M mid-term scores Gmid-term's; and the last one contains N final exam scores Gfinal's. Each score occupies a line with the format: StudentID Score, where StudentID is a string of no more than 20 English letters and digits, and Score is a nonnegative integer (the maximum score of the online programming is 900, and that of the mid-term and final exams is 100).

Output Specification:

For each case, print the list of students who are qualified for certificates. Each student occupies a line with the format:

StudentID Gp Gmid-term Gfinal G

If some score does not exist, output "-1" instead. The output must be sorted in descending order of their final grades (G must be rounded up to an integer). If there is a tie, output in ascending order of their StudentID's. It is guaranteed that the StudentID's are all distinct, and there is at least one qualified student.

Sample Input:

6 6 7
01234 880
a1903 199
ydjh2 200
wehu8 300
dx86w 220
missing 400
ydhfu77 99
wehu8 55
ydjh2 98
dx86w 88
a1903 86
01234 39
ydhfu77 88
a1903 66
01234 58
wehu8 84
ydjh2 82
missing 99
dx86w 81
Sample Output:
missing 400 -1 99 99
ydjh2 200 98 82 88
dx86w 220 88 81 84
wehu8 300 55 84 84

分析:

1 因为所有人必须要G编程>=200分,所以用v数组保存所有G编程>=200的人,(一开始gm和gf都为-1),用map映射保存名字所对应v中的下标(为了避免与“不存在”混淆,保存下标+1,当为0时表示该学生的姓名在v中不存在)

2 G期中中出现的名字,如果对应的map并不存在(==0),说明该学生编程成绩不满足条件,则无须保存该学生信息。将存在的人的期中考试成绩更新

3 G期末中出现的名字,也必须保证在map中存在。先更新G期末和G总为新的成绩,当G期末<G期中时再将G总更新为(G期中x 40% + G期末x 60%)

4 将v数组中所有G总满足条件的放入ans数组中,对ans排序(总分递减,总分相同则姓名递增),最后输出ans中的学生信息
 

//1630. 期终成绩
//
//对于在中国大学 MOOC 学习“数据结构”课程的学生,想要获得一张 合格证书,
//必须首先获得不少于 200分的在线编程作业分,然后总评获得不少于 60分(满分 100)。
//
//总评成绩的计算公式为 G = (Gmid−term×40 % +Gfinal×60%),
//如果 Gmid−term > Gfinal;否则总评 G 就是 Gfinal。
//
//这里 Gmid−term和 Gfinal分别为学生的 期中 和 期末 成绩。
//
//现在的问题是,每次考试都产生一张独立的成绩单。
//
//本题就请你编写程序,把不同的成绩单合为一张。
//
//输入格式
//输入在第一行给出 3个整数,分别是 P(做了在线编程作业的学生数)、
//M(参加了期中考试的学生数)、N(参加了期末考试的学生数)。
//
//接下来有三块输入。
//
//第一块包含 P个在线编程成绩 Gp;
//
//第二块包含 M个期中考试成绩 Gmid−term;
//
//第三块包含 N个期末考试成绩 Gfinal。
//
//每个成绩占一行,格式为:学生学号 分数。
//
//其中 学生学号 为不超过 20个字符的英文字母和数字;
//分数 是非负整数(编程总分最高为 900分,期中和期末的最高分为 100分)。
//
//输出格式
//打印出 获得合格证书 的学生名单。
//
//每个学生占一行,格式为:
//
//学生学号 Gp Gmid−term Gfinal G
//如果有的成绩不存在(例如某人没参加期中考试),则在相应的位置输出“−1”。
//
//输出顺序为按照总评分数(四舍五入精确到整数)递减。
//
//若有并列,则按学号递增。
//
//题目保证学号没有重复,且至少存在 1个合格的学生。
//
//数据范围
//1≤P, M, N≤10000
//输入样例:
//6 6 7//P(做了在线编程作业的学生数)、M(参加了期中考试的学生数)、N(参加了期末考试的学生数)。
//01234 880//第一块包含 P个在线编程成绩 Gp;
//a1903 199
//ydjh2 200
//wehu8 300
//dx86w 220
//missing 400
//ydhfu77 99//第二块包含 M个期中考试成绩 Gmid−term;
//wehu8 55
//ydjh2 98
//dx86w 88
//a1903 86
//01234 39
//ydhfu77 88//第三块包含 N个期末考试成绩 Gfinal。
//a1903 66
//01234 58
//wehu8 84
//ydjh2 82
//missing 99
//dx86w 81
//输出样例:
//missing 400 - 1 99 99
//ydjh2 200 98 82 88
//dx86w 220 88 81 84
//wehu8 300 55 84 84


#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include <unordered_set>
#include <set>
#include <unordered_map>
#include<algorithm>
#include<deque>
#include <math.h>
#include<cstdio>
using namespace std;

//yxc:排序题,简单的
struct Student{
    string id;
    int p, m, f, s;//编程成绩,期中成绩,期末成绩,总评分

    //构造函数,上述成绩 默认值为-1,此分数没有录入时,默认值就是-1
    Student() : p(-1), m(-1), f(-1), s(0) {}

    //caculate,计算总评分
    void calc()
    {
        if (f >= m) {//如果 Gmid−term > Gfinal;
            s = f;//否则总评 G 就是 Gfinal。
        }
        //round是#include <cmath>里的函数,把小数四舍五入到整数
        else s = round(m * 0.4 + f * 0.6);
    }

    bool operator< (const Student& t) const
    {
        if (s != t.s) return s > t.s;
        return id < t.id;
    }
};
bool cmp(Student a, Student b) {
    if (a.s != b.s)return a.s > b.s;//输出顺序为按照总评分数(四舍五入精确到整数)递减。
    else return a.id < b.id;//若有并列,则按学号递增。
}
class Solution {
public:
	void func() {
        //P(做了在线编程作业的学生数)、
        //M(参加了期中考试的学生数)、N(参加了期末考试的学生数)。
        int p, m, n;
        cin >> p >> m >> n;
        //由学生id到Student的映射,如果不弄这个map映射,插入此id的各个分数时,
        //还得遍历学生数组Student[N]了,复杂度高
        unordered_map<string, Student> hash;
        string id;//学生id
        int s;//分数
        for (int i = 0; i < p; i++){
            cin >> id >> s;//输入id和编程分数
            hash[id].id = id;//存储id
            hash[id].p = s;//存储编程分数
        }

        for (int i = 0; i < m; i++) {
            cin >> id >> s;
            hash[id].id = id;
            hash[id].m = s;//存储期中分数
        }

        for (int i = 0; i < n; i++) {
            cin >> id >> s;
            hash[id].id = id;
            hash[id].f = s;//存储期末成绩
        }

        //存放合格的学生
        vector<Student> students;
        //遍历unordered_map<string, Student> hash;
        for (auto item : hash){
            auto stu = item.second;//item.second是结构体Student

            stu.calc();//计算出总评分,stu结构体里的s是总评分
            if (stu.p >= 200 && stu.s >= 60)
                students.push_back(stu);//合格学生放入vector中
        }

        sort(students.begin(), students.end());//排序

        //遍历输出
        for (auto s : students) {
            cout << s.id << ' ' << s.p << ' ' << s.m << ' ' << s.f << ' ' << s.s << endl;
        }
            
	}
};

class Solution2 {
public:
	void func() {

	}
};

int main() {
	Solution s;
	s.func();
	return 0;
}




九哈希表8 1638. 哈希 - 平均查找时间 PAT甲级真题1145

1638. 哈希 - 平均查找时间

这个问题的任务很简单:

首先将一个由若干个不同正整数构成的整数序列插入到一个哈希表中,
然后尝试从表中查找另一个整数键值序列,
并输出平均查找时间(查找时间指查找某个值是否在表中所进行的比较操作的次数)。

哈希函数定义为 H(key) = key % TSize,
其中 TSize是哈希表的最大大小。

利用只具有正增量的二次探测法来解决冲突。

注意,哈希表的大小最好是素数,如果用户给出的最大大小不是素数,
则必须将表大小重新定义为 大于用户给出的大小的最小素数。

输入格式
第一行包含三个正整数 MSize, N, M,
分别表示用户定义的表的大小,插入整数的数量,查找键值的数量。

第二行包含 N个不同的正整数,表示插入序列。

第三行包含 M个正整数,表示键值序列。

同行数字之间用空格隔开,两个序列中包含的整数均不超过 105。

输出格式
如果无法插入一些数字,则将其按顺序以如下格式输出,
每个数字占一行:X cannot be inserted.其中 X 表示无法插入的数字。

最后一行输出 M次查找的平均查找时间,保留一位小数。

注意: 如果查找了 TSize次,每次查找的位置上均有数,
但都不等于要查找的数,则认为查找时间是 TSize + 1。

数据范围
1≤MSize, N, M≤104
输入样例:
4 5 4
10 6 4 15 11
11 4 15 2
输出样例:
15 cannot be inserted.
2.8

The task of this problem is simple: insert a sequence of distinct positive integers into a hash table first. Then try to find another sequence of integer keys from the table and output the average search time (the number of comparisons made to find whether or not the key is in the table). The hash function is defined to be “H(key) = key % TSize” where TSize is the maximum size of the hash table. Quadratic probing (with positive increments only) is used to solve the collisions.
Note that the table size is better to be prime. If the maximum size given by the user is not prime, you must re-define the table size to be the smallest prime number which is larger than the size given by the user.
Input Specification:
Each input file contains one test case. For each case, the first line contains two positive numbers: MSize, N, and M, which are the user-defined table size, the number of input numbers, and the number of keys to be found, respectively. All the three numbers are no more than 104. Then N distinct positive integers are given in the next line. All the numbers in a line are separated by a space and are no more than 105.
Output Specification:
For each test case, in case it is impossible to insert some number, print in a line “X cannot be inserted.” where X is the input number. Finally print in a line the average search time for all the M keys, accurate up to 1 decimal place.
Sample Input:
4 5 4
10 6 4 15 11
11 4 15 2
Sample Output:
15 cannot be inserted.
2.8

题目大意:给定一个序列,用平方探测法解决哈希冲突,然后给出m个数字,如果这个数字不能够被插入就输出”X cannot be inserted.”,然后输出这m个数字的平均查找时间

分析:先找到大于tsize的最小的素数为真正的tsize,然后建立一个tsize长度的数组。首先用平方探测法插入数字a,每次pos = (a + j * j) % tsize,j是从0~tsize-1的数字,如果当前位置可以插入就将a赋值给v[pos],如果一次都没有能够插入成功就输出”X cannot be inserted.”。其次计算平均查找时间,每次计算pos = (a + j * j) % tsize,其中j <= tsize,如果v[pos]处正是a则查找到了,则退出循环,如果v[pos]处不存在数字表示没查找到,那么也要退出循环。每次查找的时候,退出循环之前的j就是这个数字的查找长度。最后ans除以m得到平均查找时间然后输出~
 

//1638. 哈希 - 平均查找时间
//
//这个问题的任务很简单:
//
//首先将一个由若干个不同正整数构成的整数序列插入到一个哈希表中,
//然后尝试从表中查找另一个整数键值序列,
//并输出平均查找时间(查找时间指查找某个值是否在表中所进行的比较操作的次数)。
//
//哈希函数定义为 H(key) = key % TSize,
//其中 TSize是哈希表的最大大小。
//
//利用只具有正增量的二次探测法来解决冲突。
//
//注意,哈希表的大小最好是素数,如果用户给出的最大大小不是素数,
//则必须将表大小重新定义为 大于用户给出的大小的最小素数。
//
//输入格式
//第一行包含三个正整数 MSize, N, M,
//分别表示用户定义的表的大小,插入整数的数量,查找键值的数量。
//
//第二行包含 N个不同的正整数,表示插入序列。
//
//第三行包含 M个正整数,表示键值序列。
//
//同行数字之间用空格隔开,两个序列中包含的整数均不超过 105。
//
//输出格式
//如果无法插入一些数字,则将其按顺序以如下格式输出,
//每个数字占一行:X cannot be inserted.其中 X 表示无法插入的数字。
//
//最后一行输出 M次查找的平均查找时间,保留一位小数。
//
//注意: 如果查找了 TSize次,每次查找的位置上均有数,
//但都不等于要查找的数,则认为查找时间是 TSize + 1。
//
//数据范围
//1≤MSize, N, M≤104
//输入样例:
//4 5 4
//10 6 4 15 11
//11 4 15 2
//输出样例:
//15 cannot be inserted.
//2.8



#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include <unordered_set>
#include <set>
#include <unordered_map>
#include<algorithm>
#include<deque>
#include <math.h>
#include<cstdio>
using namespace std;
const int N = 10010;

/// <summary>
/// 输入样例:
/// 4 5 4
/// 10 6 4 15 11
/// 11 4 15 2
/// 
/// 插入:
/// 先插入10 6 4
/// 0  1  2  3  4---->这是下标
/// 10 6        4
/// 
/// 再插入15时,根据开放定址法,往前1,4,9,16,25,分别落在下标1,4,4,1,0均无法插入,
/// 插入次数超过哈希表长度5,插入失败!
/// 
/// 再插入11,11%5=1,下标1被占,按照1,4,9,16,25前进,11%5+1=2,下标2空着,插入到下标2位置
/// 0  1  2  3  4---->这是下标
/// 10 6  11    4
/// 
/// 查询:
/// 11 4 15 2
/// 查找11,11%5=1,下标1有6,11%5+1=2,下标2是11,找到,所以查询了2次。
/// 查找4,4%5=4,下标4就是4,找到,查询了1次,
/// 查找15,按照15%5+1,2,4,9,16,25,都被占用,
///     查找TSize=5次也找不到,所以算查询了TSize+1=6次
/// 查找2,2%5=2,下标2是11,再查2%5+1=3,下标3是空的,遇到空的就停止,查找了2次
/// 
/// 所以查询4个数字,一共查找了2+1+6+2=11次,
/// 平均查找次数为11/4=2.75次,保留一位小数=2.8
/// 是个模拟题
/// </summary>
int s, n, m;
int h[N];
class Solution {
public:
    //这些都同 九哈希表6 1564. 哈希 PAT甲级真题1078
    //判断是否质数
    bool is_prime(int x)
    {
        if (x == 1) return false;

        for (int i = 2; i * i <= x; i++)
            if (x % i == 0)
                return false;

        return true;
    }

    int find(int x, int& cnt)
    {
        int t = x % s;

        cnt = 1;//下标t一次到位,也算查询一次
        //遍历哈希表长度s,每遍历一次,查询次数++
        for (int k = 0; k < s; k++, cnt++)
        {
            int i = (t + k * k) % s; //开放寻址法是平方滴1, 4, 9, 16, 25滴往前跳
            if (!h[i] || h[i] == x) return i;//h[i]==0没找到,h[i]==x找到时,返回下标i
        }
        return -1;//查询了哈希表长度s次,都没找到,返回-1
    }

	void func() {
        cin >> s >> n >> m;

        while (!is_prime(s)) s++;//如果不是质数,哈希表大小++

        for (int i = 0; i < n; i++) {
            int x, count;
            cin >> x;

            int t = find(x, count);
            if (t == -1) {//若t=-1代表无法插入
                printf("%d cannot be inserted.\n", x);
            }
            else h[t] = x;//否则将x插入哈希表下标为t处
        }

        int cnt = 0;//记录m个数字的总查询数
        for (int i = 0; i < m; i++) {//输入m个需要查询的数字
            int x, count;
            cin >> x;
            find(x, count);//查询x需要的次数是count
            cnt += count;//全加起来
        }
        //输出 平均查询次数=总查询次数/m,%.1lf保留1位小数
        printf("%.1lf\n", (double)cnt / m);
	}
};

class Solution2 {
public:
	void func() {

	}
};

int main() {
	Solution s;
	s.func();
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值