Hash practice questions

Commonly used problems in the hash area include: judging whether a certain m positive integer among 5 positive integers has appeared, and how many times it has appeared-declaration bool/int hashTable[maxn] = {false}/{0} . The essence of the method is to directly use the input integer as the subscript of the array to count the nature of the number, that is, hash(key)=key direct addressing, which is the most common and practical hash application. To be more complicated, there is a secondary mapping. Mastering these two ideas is almost the same.
Some content of this article comes from https://blog.csdn.net/myRealization/article/details/80154726

Who are your potential friends [★]

http://codeup.cn/problem.php?cid=100000582&pid=0

  • The title describes
    "smelly similar"-this is a vocabulary we like to use when describing friends. Two people being friends usually means that they have many interests in common. However, as an otaku, you find that there are not many opportunities for you to get to know each other. Fortunately, you accidentally got a copy of book borrowing records from the Peking University Library, so you choose to stay up late to program, hoping to discover potential friends.
    First, you sorted out the borrowing records, numbering N readers as 1, 2,..., N, and numbering M books as 1, 2,..., M. At the same time, in accordance with the principle of "smelly similar", people who like to read the same book as you are your potential friends. Your task now is to calculate from this loan record how many potential friends each person has.

  • Enter
    two integers N, M, 2 <= N, M <= 200 in the first line of each case. Next, there are N rows, each of the i-th row (i = 1,2,...,N) has a number, which represents the number P (1<=P<=M) of reader i-1's favorite book

  • Output
    Each case includes N rows, each with a number, and the number in the i-th row indicates how many potential friends reader i has. If i and no one have a favorite book in common, output "BeiJu" (ie tragedy, ^ ^)

样例输入 
4 5
2
3
2
1
样例输出	
1
BeiJu
1
BeiJu

Use array as subscript, directly address hash

#include<cstdio>
int main(void)
{
    
    
	int M,N;
	int i;
	while(scanf("%d%d",&N,&M)!=EOF)
	{
    
    
	    int a[M+1]={
    
    0};
	    int student[N+1]={
    
    0};
		for(i=1;i<=N;i++)
		{
    
    
			scanf("%d",&student[i]);
			a[student[i]]++;
		}
		for(i=1;i<=N;i++)
		{
    
    
			if( (a[student[i]]-1) == 0 )
			{
    
    
				printf("BeiJu\n");
				continue;
			}
			printf("%d\n",a[student[i]]-1);
		}
	}
	return 0;
}

Is the only one【★】

  • Title Description
    To people on Mars, being unique is so important that their lottery tickets are also designed in a unique way. The rules for winning are simple: a bet is to choose a number from [1, 10 4 ]. The first person to bet on the unique number wins. For example, if 7 people bet on 5 31 5 88 67 88 88 17, then the second person to bet 31 wins.
  • Input
    Each input file contains a test case. Each case consists of a line starting with a positive integer N (N<=10 5 ), and then N bets. The numbers are separated by spaces.
  • Output
    For each test case, print the winning number on one line. If there is no winner, print "None".
样例输入
7 5 31 5 88 67 88 17
5 888 666 666 888 888
样例输出
31
None

Use array as subscript, directly address hash

#include<cstdio>
int a[10005];
int main(void)
{
    
    
	int N;
	int i;
	int flag;
	while(scanf("%d",&N)!=EOF)
	{
    
    
		flag=0;
	    int student[N+1]={
    
    0};
		for(i=1;i<=N;i++)
		{
    
    
			scanf("%d",&student[i]);
			a[student[i]]++;
		}
		for(i=1;i<=N;i++)
		{
    
    
			if( a[student[i]] == 1 )
			{
    
    
				printf("%d\n",student[i]);
				flag=1;
				break;
			}
		}
		if(!flag)
		{
    
    
			printf("None\n");
		}
	}
	return 0;
}

String subtraction【★★】

  • Title description
    Given two strings S1 and S2, S=S1-S2 is defined as the remaining string after all the characters in S. 2 from S1. Your task is just to calculate S1-S2 for any given string. However, doing this may not be that simple. quickly.
  • Input
    Each input file contains a test case. Each case contains two rows, giving S1 and S2 respectively. The string length of these two strings does not exceed 10. 4. Ensure that all characters are visible ASCII codes and spaces, and a new line character indicates the end of the string.
  • Output
    For each test case, print a line S1-S2.
样例输入
They are students.
aeiou
样例输出
Thy r stdnts.

Use array as subscript, directly address hash

#include<cstdio>
#include<cstring>
char s1[1005],s2[1005];
bool hush[130]={
    
    false};
int main(void)
{
    
    
	int i=0;
	while( gets(s1) != NULL)
	{
    
    
		gets(s2);
		for(i=0;i<strlen(s2);i++)
		{
    
    
			hush[s2[i]]=true;//确定重复
		}
		for(i=0;i<strlen(s1);i++)
		{
    
    
			if(hush[s1[i]]==false)
				printf("%c",s1[i]);
		}
	}
	return 0;
}

Group Statistics【★★★】

  • Title description
    First enter a group of numbers, then enter its group, count the number of occurrences according to the group and output, see the sample.

  • The
    first line of input represents the number of samples m. For each sample, the number of numbers in the first line is n, the next two lines have n numbers, the first line has n numbers, and the second line has n numbers. The numbers correspond to the grouping of each number in the previous row, and n does not exceed 100.

  • Output
    Output m lines, see the example for the format, sort from small to large.

样例输入 
1
7
3 2 3 8 8 2 3
1 2 3 2 1 3 1
样例输出	
1={2=0,3=2,8=1}
2={2=1,3=0,8=1}
3={2=1,3=1,8=0}

Analysis: This topic can be said to be a collection of integer hash ideas, which is worthy of careful analysis.

  • First of all, the title says that the amount of input data does not exceed 100, and the category does not exceed 100, but it does not say the specific range of the data. It may exceed the range of the array subscript when an integer is used as an array subscript. In theory, for this type of problem , To exchange space for time, the required data should not exceed 10 6 . Therefore, to count whether the input data and group have appeared, you can open hashTable[100100] as big.
  • Deduplication operation. With a hash table that identifies whether the data appears, it can be done very simply.
    The answer matrix is ​​a two-dimensional array of secondary mapping, and the number of occurrences of the data of the corresponding group can be found directly through the group and data.
    A 50% error occurs: If the two-dimensional array is too small, it is easy to overflow, so record the largest value in the first row of data and use +10 as the number of columns in the two-dimensional array to solve the problem.

Ideas:

  1. Enter the first row of data and store it in data[]. At the same time, use hashTable1[] to deduplicate, store the deduplicated numbers in nums[], and sort them.
  2. Enter the group in the second row and store it in group[]. At the same time, use the hashTable2[] function to deduplicate, store the deduplicated numbers in g[] and sort them.
  3. At the same time, group[] and data[] are mapped to ans[][], where i is the group and j is the number in ans[i][j]. a[i][j] is the number of occurrences of j in the i-th group.
  4. Traverse the output.
说白了就是用一个数组输入第一行的数。
再用一个数组保存去重后的数。然后排序。

第二行也是同理的。
最后用一个映射的二维数组统计出现的次数。

Use array as subscript, direct addressing hash, and secondary mapping hash

#include <cstdio>
#include <algorithm>
using namespace std;

int main() {
    
    
	int m;
	scanf("%d", &m);
	while (m--) {
    
    
		int n, maxCol = 0, data[110], group[110]; //分别记录输入的数据和分组
		scanf("%d", &n);
		
		//nums记录输入的数据去重后的数据  
		int nums[120], len1 = 0;
		//使用哈希表对data进行存在标识, 以便去重 
		bool hashTable1[100100] = {
    
    false}; 
		for (int i = 0; i < n; i++) {
    
     
			scanf("%d", &data[i]);      //边录入边去重 
			if (!hashTable1[data[i]]) {
    
     //如果这个数据尚未被记录 
	    		nums[len1++] = data[i]; 
	            hashTable1[data[i]] = true; 
			}
			//得到最大的数, 方便答案直接映射而不溢出 
			if (maxCol < data[i]) maxCol = data[i];  
		} 
		sort(nums, nums + len1); //数据从小到大存放在nums中, 无重复  
		
		//g记录输入的组别去重后的数据  
		int g[120], len2 = 0; 
		//使用哈希表对group进行存在标识, 以便去重
		bool hashTable2[100100] = {
    
    false};
		/*二维答案表,元素ans[g[i]][nums[j]]表示g[i]组中对应的nums[j]出现的次数 
		ans[i][j], i为分组, j为数, a[i][j]为第i组的j数出现的次数 */
		int ans[n + 10][maxCol + 10] = {
    
    0};  
		for (int i = 0; i < n; i++) {
    
    
			scanf("%d", &group[i]);
			ans[group[i]][data[i]]++; 
			if (!hashTable2[group[i]]) {
    
     //如果这个组别尚未被记录 
			   g[len2++] = group[i];  
			   hashTable2[group[i]] = true;
            } 
		}
		sort(g, g + len2); //组别从小到大存放在g中, 无重复 
	
		//输出结果 
		for (int i = 0; i < len2; i++) {
    
    
			printf("%d={", g[i]);
			for (int j = 0; j < len1; j++) {
    
    
				printf("%d=%d", nums[j], ans[g[i]][nums[j]]);
				if (j < len1 - 1) printf(",");
				else printf("}\n");
			}
		} 
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/qq_46527915/article/details/114678579