算法笔记 上机训练实战指南 第4章 入门篇(2) --算法初步 4.2散列 学习笔记
旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现。现在给出应该输入的一段文字、以及实际被输入的文字,请你列出肯定坏掉的那些键。
输入格式:
输入在 2 行中分别给出应该输入的文字、以及实际被输入的文字。每段文字是不超过 80 个字符的串,由字母 A-Z(包括大、小写)、数字 0-9、以及下划线 _
(代表空格)组成。题目保证 2 个字符串均非空。
输出格式:
按照发现顺序,在一行中输出坏掉的键。其中英文字母只输出大写,每个坏键只输出一次。题目保证至少有 1 个坏键。
输入样例:
7_This_is_a_test
_hs_s_a_es
输出样例:
7TI
#include<cstdio> #include<cstring> int main(){ char str1[100],str2[100]; bool HashTable[123]={false}; scanf("%s",str1); scanf("%s",str2); int len1 = strlen(str1); int len2 = strlen(str2); for(int i=0;i<len1;i++){ int j; char c1,c2; for(j=0;j<len2;j++){ c1 = str1[i]; c2 = str2[j]; if(c1 >= 'a' && c1 <= 'z') c1 -= 32; if(c2 >= 'a' && c2 <= 'z') c2 -= 32; if(c1 == c2) break; } if(j==len2 && HashTable[c1]==false){ printf("%c",c1); HashTable[c1] = true; } } return 0; }
旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现。现在给出应该输入的一段文字、以及坏掉的那些键,打出的结果文字会是怎样?
输入格式:
输入在 2 行中分别给出坏掉的那些键、以及应该输入的文字。其中对应英文字母的坏键以大写给出;每段文字是不超过 1 个字符的串。可用的字符包括字母 [a
-z
, A
-Z
]、数字 0
-9
、以及下划线 _
(代表空格)、,
、.
、-
、+
(代表上档键)。题目保证第 2 行输入的文字串非空。
注意:如果上档键坏掉了,那么大写的英文字母无法被打出。
输出格式:
在一行中输出能够被打出的结果文字。如果没有一个字符能被打出,则输出空行。
输入样例:
7+IE.
7_This_is_a_test.
输出样例:
_hs_s_a_tst
#include<cstdio> #include<iostream> #include<cstring> using namespace std; int main(){ bool HashTable[256]; memset(HashTable,true,sizeof(HashTable)); char str[100010]; fgets(str,100010,stdin); int len = strlen(str); for(int i=0;i<len;i++){ if(str[i]>='A' && str[i]<='Z'){ str[i] = str[i] - 'A' +'a'; } HashTable[str[i]] = false; } fgets(str,100010,stdin); len = strlen(str); for(int i=0;i<len;i++){ int low; if(str[i]>='A' && str[i]<='Z'){ low = str[i] - 'A' +'a'; if(HashTable[low]==true && HashTable['+']==true){ printf("%c",str[i]); } }else if(HashTable[str[i]] == true){ printf("%c",str[i]); } } printf("\n"); return 0; }
PAT B1038 统计同成绩学生 (20分)
本题要求读入 N 名学生的成绩,将获得某一给定分数的学生人数输出。
输入格式:
输入在第 1 行给出不超过 1 的正整数 N,即学生总人数。随后一行给出 N 名学生的百分制整数成绩,中间以空格分隔。最后一行给出要查询的分数个数 K(不超过 N 的正整数),随后是 K 个分数,中间以空格分隔。
输出格式:
在一行中按查询顺序给出得分等于指定分数的学生人数,中间以空格分隔,但行末不得有多余空格。
输入样例:
10
60 75 90 55 75 99 82 90 75 50
3 75 90 88
输出样例:
3 2 0
#include<cstdio> int score[110] = {0}; int main(){ int n; scanf("%d",&n); for(int i=0;i<n;i++){ int temp; scanf("%d",&temp); score[temp]++; } int num; scanf("%d",&num); int *tempnum = new int[num]; for(int i=0;i<num;i++){ scanf("%d",&tempnum[i]); } for(int i=0;i<num;i++){ printf("%d",score[tempnum[i]]); if( i <num-1){ printf(" "); } } return 0; }
Eva would like to make a string of beads with her favorite colors so she went to a small shop to buy some beads. There were many colorful strings of beads. However the owner of the shop would only sell the strings in whole pieces. Hence Eva must check whether a string in the shop contains all the beads she needs. She now comes to you for help: if the answer is Yes
, please tell her the number of extra beads she has to buy; or if the answer is No
, please tell her the number of beads missing from the string.
For the sake of simplicity, let's use the characters in the ranges [0-9], [a-z], and [A-Z] to represent the colors. For example, the 3rd string in Figure 1 is the one that Eva would like to make. Then the 1st string is okay since it contains all the necessary beads with 8 extra ones; yet the 2nd one is not since there is no black bead and one less red bead.
Figure 1
Input Specification:
Each input file contains one test case. Each case gives in two lines the strings of no more than 1000 beads which belong to the shop owner and Eva, respectively.
Output Specification:
For each test case, print your answer in one line. If the answer is Yes
, then also output the number of extra beads Eva has to buy; or if the answer is No
, then also output the number of beads missing from the string. There must be exactly 1 space between the answer and the number.
Sample Input 1:
ppRYYGrrYBR2258
YrR8RrY
Sample Output 1:
Yes 8
Sample Input 2:
ppRYYGrrYB225
YrR8RrY
Sample Output 2:
No 2
#include<cstdio> #include<cstring> int hashtable[80]={0}; int change(char c){ if(c >= '0' && c <= '9') return c - '0'; else if(c >= 'A' && c <= 'Z'){ return c - 'A' + 10; } else if(c >= 'a' && c <= 'z'){ return c - 'a' + 36; } } int main(){ char str1[1010],str2[1010]; scanf("%s",str1); scanf("%s",str2); int len1 = strlen(str1); int len2 = strlen(str2); for(int i=0;i<len1;i++){ int id = change(str1[i]); hashtable[id]++; } int miss = 0; for(int i=0;i<len2;i++){ int id = change(str2[i]); if(hashtable[id]>0){ hashtable[id]--; }else{ miss++; } } if(miss>0) printf("No %d",miss); else printf("Yes %d",len1-len2); return 0; }
请编写程序,找出一段给定文字中出现最频繁的那个英文字母。
输入格式:
输入在一行中给出一个长度不超过 1000 的字符串。字符串由 ASCII 码表中任意可见字符及空格组成,至少包含 1 个英文字母,以回车结束(回车不算在内)。
输出格式:
在一行中输出出现频率最高的那个英文字母及其出现次数,其间以空格分隔。如果有并列,则输出按字母序最小的那个字母。统计时不区分大小写,输出小写字母。
输入样例:
This is a simple TEST. There ARE numbers and other symbols 1&2&3...........
输出样例:
e 7
#include<cstdio> #include<cstring> const int maxn = 1010; char str[maxn]; int hashtable[30]={0}; int main(){ fgets(str,maxn,stdin); int len = strlen(str); for(int i=0;i<len;i++){ if(str[i]>='a' && str[i]<='z'){ hashtable[str[i] - 'a']++; }else if(str[i]>='A' && str[i]<='Z'){ hashtable[str[i] - 'A']++; } } int max=0; int k; for(int j=0;j<30;j++){ if(hashtable[j]>max){ max = hashtable[j]; k =j; } } printf("%c %d\n",'a'+k,max); return 0; }
给定一个长度不超过 1 的、仅由英文字母构成的字符串。请将字符重新调整顺序,按 PATestPATest....
这样的顺序输出,并忽略其它字符。当然,六种字符的个数不一定是一样多的,若某种字符已经输出完,则余下的字符仍按 PATest 的顺序打印,直到所有字符都被输出。
输入格式:
输入在一行中给出一个长度不超过 1 的、仅由英文字母构成的非空字符串。
输出格式:
在一行中按题目要求输出排序后的字符串。题目保证输出非空。
输入样例:
redlesPayBestPATTopTeePHPereatitAPPT
输出样例:
PATestPATestPTetPTePePee
#include<cstdio> #include<cstring> using namespace std; const int maxn = 10010; char str[maxn]; int hashtable[6]={0}; char dict[6]={'P','A','T','e','s','t'}; int main(){ fgets(str,maxn,stdin); int len = strlen(str); int sum = 0; for(int i=0;i<len;i++){ for(int j=0;j<6;j++){ if(str[i]==dict[j]){ hashtable[j]++; sum++; } } } while(sum!=0){ for(int i=0;i<6;i++){ if(hashtable[i]>0){ printf("%c",dict[i]); hashtable[i]--; sum--; } } } return 0; }
编程团体赛的规则为:每个参赛队由若干队员组成;所有队员独立比赛;参赛队的成绩为所有队员的成绩和;成绩最高的队获胜。
现给定所有队员的比赛成绩,请你编写程序找出冠军队。
输入格式:
输入第一行给出一个正整数 N(≤),即所有参赛队员总数。随后 N 行,每行给出一位队员的成绩,格式为:队伍编号-队员编号 成绩
,其中队伍编号
为 1 到 1000 的正整数,队员编号
为 1 到 10 的正整数,成绩
为 0 到 100 的整数。
输出格式:
在一行中输出冠军队的编号和总成绩,其间以一个空格分隔。注意:题目保证冠军队是唯一的。
输入样例:
6
3-10 99
11-5 87
102-1 0
102-3 100
11-9 89
3-2 61
输出样例:
11 176
#include<cstdio> const int maxn = 10010; int hashtable[maxn]={0}; int main(){ int n; scanf("%d",&n); for(int i=0;i<n;i++){ int team,num,score; scanf("%d-%d %d",&team,&num,&score); hashtable[team] += score; } int max=0,k; for(int i=0;i<maxn;i++){ if(hashtable[i]>max){ k = i; max = hashtable[i]; } } printf("%d %d",k,max); return 0; }
Being unique is so important to people on Mars that even their lottery is designed in a unique way. The rule of winning is simple: one bets on a number chosen from [1]. The first one who bets on a unique number wins. For example, if there are 7 people betting on { 5 31 5 88 67 88 17 }, then the second one who bets on 31 wins.
Input Specification:
Each input file contains one test case. Each case contains a line which begins with a positive integer N (≤) and then followed by N bets. The numbers are separated by a space.
Output Specification:
For each test case, print the winning number in a line. If there is no winner, print None
instead.
Sample Input 1:
7 5 31 5 88 67 88 17
Sample Output 1:
31
Sample Input 2:
5 888 666 666 888 888
Sample Output 2:
None
#include<cstdio> const int maxn = 100010; int a[maxn],hashtable[maxn]={0}; int main(){ int n; scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d",&a[i]); hashtable[a[i]]++; } int ans = -1; for(int i=0;i<n;i++){ if(hashtable[a[i]]==1){ ans = a[i]; break; } } if(ans == -1){ printf("None\n"); }else{ printf("%d\n",ans); } return 0; }
Given two strings S1 and S2, S=S1−S2 is defined to be the remaining string after taking all the characters in S2 from S1. Your task is simply to calculate S1−S2 for any given strings. However, it might not be that simple to do it fast.
Input Specification:
Each input file contains one test case. Each case consists of two lines which gives S1 and S2, respectively. The string lengths of both strings are no more than 1. It is guaranteed that all the characters are visible ASCII codes and white space, and a new line character signals the end of a string.
Output Specification:
For each test case, print S1−S2 in one line.
Sample Input:
They are students.
aeiou
Sample Output:
Thy r stdnts.
#include<cstdio> #include<iostream> #include<cstring> using namespace std; const int maxn=10010; char str1[maxn],str2[maxn]; bool HashTable[128]; int main(){ fgets(str1,maxn,stdin); fgets(str2,maxn,stdin); int len1 = strlen(str1); int len2 = strlen(str2); for(int i=0;i<len2;i++){ HashTable[str2[i]] = true; } for(int i=0;i<len1;i++){ if(HashTable[str1[i]] != true){ printf("%c",str1[i]); } } return 0; }
卡拉兹(Callatz)猜想已经在1001中给出了描述。在这个题目里,情况稍微有些复杂。
当我们验证卡拉兹猜想的时候,为了避免重复计算,可以记录下递推过程中遇到的每一个数。例如对 n=3 进行验证的时候,我们需要计算 3、5、8、4、2、1,则当我们对 n=5、8、4、2 进行验证的时候,就可以直接判定卡拉兹猜想的真伪,而不需要重复计算,因为这 4 个数已经在验证3的时候遇到过了,我们称 5、8、4、2 是被 3“覆盖”的数。我们称一个数列中的某个数 n 为“关键数”,如果 n 不能被数列中的其他数字所覆盖。
现在给定一系列待验证的数字,我们只需要验证其中的几个关键数,就可以不必再重复验证余下的数字。你的任务就是找出这些关键数字,并按从大到小的顺序输出它们。
输入格式:
每个测试输入包含 1 个测试用例,第 1 行给出一个正整数 K (<),第 2 行给出 K 个互不相同的待验证的正整数 n (1)的值,数字间用空格隔开。
输出格式:
每个测试用例的输出占一行,按从大到小的顺序输出关键数字。数字间用 1 个空格隔开,但一行中最后一个数字后没有空格。
输入样例:
6
3 5 6 7 8 11
输出样例:
7 6
#include<cstdio> #include<algorithm> using namespace std; bool cmp(int a,int b){ return a>b; } int main(){ int n; bool HashTable[10000]={false}; int a[110]; scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d",&a[i]); int m = a[i]; while(m!=1){ if(m%2 == 1){ m = (3*m + 1)/2; }else{ m = m /2; } HashTable[m] = true; } } int count = 0; for(int i=0;i<n;i++){ if(HashTable[a[i]]==false){ count++; } } sort(a,a+n,cmp); for(int i=0;i<n;i++){ if(HashTable[a[i]] == false){ printf("%d",a[i]); count--; if(count > 0){ printf(" "); } } } return 0; }
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 1 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 (≤, the total number of coins) and M (≤, 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
#include<cstdio> const int maxm = 1010; int hashtable[maxm]={0}; int main(){ int n,m; scanf("%d %d",&n,&m); for(int i=0;i<n;i++){ int a; scanf("%d",&a); hashtable[a]++; } for(int i=0;i<maxm;i++){ if(hashtable[i] && hashtable[m-i]){ if(i==m-i && hashtable[i]<=1){ continue; } printf("%d %d",i,m-i); return 0; } } printf("No Solution\n"); return 0; }