4.2散列

目录

4.2散列

PAT A1084 Broken Keyboard (20 分)

PAT A1092 To Buy or Not to Buy (20 分)

PAT B1042 字符统计 (20 分)

PAT B1043 输出PATest (20 分)

PAT B1047 编程团体赛 (20 分)

PAT A1041 Be Unique (20 分)

PAT A1050 String Subtraction (20 分)

PAT B1005 继续(3n+1)猜想 (25 分)

PAT A1048 Find Coins (25 分)


学习散列舒服多了,难度比排序低太多,也算是长自信的一个环节吧..

主要的套路方法比较单一,就不列举花里胡哨的方法了,只列举主要要用的方法和实际程序。

4.2散列

定义:将元素转化为一个整数,并尽量使得该整数可以唯一表示该元素

最基础也是最广泛的使用方法为

bool hashtable[x]={false};        //代表x没出现过

int hashtable[x]={0};             //代表x出现次数为0

PAT的主要涉及的也是这俩种方法

直接上题目

注意PAT的c++语言是不能用gets函数的,为了安全的问题=.=,但是c 还是可以的,所以提交的话用c语言的格式,库函数要改成stdio.h啥的用bool的加个stdbool.h

PAT A1084 Broken Keyboard (20 分)

#include<cstdio>
#include<cstring>
int main()
{
    char alpha[100];
    char alphb[100];
    bool hashtable[128]={false}; 
    int j=0;
    gets(alpha);
    gets(alphb);
    int lena=strlen(alpha);
    int lenb=strlen(alphb);
    for(int i=0;i<lena;i++)
    {
        for(j=0;j<lenb;j++)
        {
            if(alpha[i]<='z'&&alpha[i]>='a')alpha[i]-=32;
            if(alphb[j]<='z'&&alphb[j]>='a')alphb[j]-=32;
            if(alpha[i]==alphb[j])break;
        }
        if(j==lenb&&hashtable[alpha[i]]==false){
            printf("%c",alpha[i]);
            hashtable[alpha[i]]=true;
        }
    }
    return 0;
}

这题非常的典型,可以说是套路,对于键盘上的字符,hash长度为128就够用了,方法就是求两个字符串的关系,一般都要用strlen函数,然后由于每个字符串是80个,长度很短,所以用N*M的复杂度也是可以的。因为题目是坏键盘,不区分大小写需要将小写字母转化为大写,最后将hash为false的输出就可以。

PAT A1092 To Buy or Not to Buy (20 分)

#include<cstdio>
#include<cstring>
const int maxn=1010;
char str1[maxn];
char str2[maxn];
int main()
{
    gets(str1);
    gets(str2);
    int len1=strlen(str1);
    int len2=strlen(str2);
    int flag1=0;
    int miss=0;
    int i=0,j=0;
    int hashtable[128]={0};      //设置俩个hash一个计数一个判断是否有这种珠子
    bool hash[128]={false};
    for(i=0;i<len1;i++)          //读入珠子的数量,注意复杂性不能用N*M的形式
    {
        hashtable[str1[i]]++;
        hash[str1[i]]=true;
    }
    for(j=0;j<len2;j++)           
    {
       if(hash[str1[j]]=true) {     //用减号来消除,存在俩种珠子缺少的情况
           hashtable[str2[j]]--;
           if(hashtable[str2[j]]<0){
               miss++;
               flag1=1;
            }
       }
       else {flag1 =1;miss++;}
    }
    if(flag1==1)printf("No %d",miss);
    else printf("Yes %d",len1-len2);
    return 0;
}

对于这个题目主要的方法是利用hash来单独建一个计数器如果有则+1,如果没有则-1,复杂度用的是N+M

PAT B1042 字符统计 (20 分)

#include<cstdio>
#include <cstring>
int main()
{
    char str[1010];
    int hashtable[30]={0};
    int max=0;
    gets(str);
    int len=strlen(str);
    for(int i=0;i<len;i++)
    {
        if(str[i]<='Z'&&str[i]>='A')hashtable[str[i]-'A']++;
        else if(str[i]<='z'&&str[i]>='a')hashtable[str[i]-'a']++;
    }
    for(int j=0;j<30;j++)
    {
        if(hashtable[j]>hashtable[max])max=j;
    }
    printf("%c %d",str[max],hashtable[max]);
    return 0;
}

计数器

PAT B1043 输出PATest (20 分)

#include<cstdio>
#include<cstring>
int hashtable[10]={0};
int main()
{
    char str[10010];
    char test[10]="PATest";
    int sum=0;
    gets(str);
    int len1=strlen(str);
    int len2=strlen(test);
    for(int i=0;i<len1;i++)
    {
        for(int j=0;j<6;j++)
        {
            if(str[i]==test[j]){
            hashtable[j]++;
            sum++;
            }
        }
    }
    while(sum>0){
        for(int i=0;i<6;i++)
        {
            if(hashtable[i]>0)
            {
            hashtable[i]--;
            printf("%c",test[i]);
            }
        }
    }
    return 0;
}

循环对字符串的字符计数,然后进行循环-1输出

PAT B1047 编程团体赛 (20 分)

#include<cstdio>
struct student{
    int team_N,member_N,grade;      //代表队伍编号,成员编号,分数;
}stu[10010];

int main()
{
    int N;      //为参赛队员总数
    int hashtable[10010]={0};
    int i=0;
    scanf("%d",&N);
    for(i=0;i<N;i++)
    {
        scanf("%d-%d %d",&stu[i].team_N,&stu[i].member_N,&stu[i].grade);
        hashtable[stu[i].team_N]+=stu[i].grade;
    }
    int max=0,k=0;
    for(i=0;i<N;i++)
    {
        if(hashtable[stu[i].team_N]>max)
        {
            max=hashtable[stu[i].team_N];
            k=stu[i].team_N;
        }  
    }
    printf("%d %d\n",k,max);        //输出结果
    return 0;
}

循环的使用,不用结构体也行

PAT A1041 Be Unique (20 分)

#include<cstdio>
int main()
{
    int N,M[100010];
    scanf("%d",&N);
    int i,j,flag=0;
    int hashtable[100010]={0};
    for(i=0;i<N;i++)
    {
        scanf("%d",&M[i]);
        hashtable[M[i]]++;
    }
    for(i=0;i<N;i++)
    {
        if(hashtable[M[i]]==1){
            printf("%d",M[i]);
            flag=1;
            break;
        }
    }
    if(flag==0)printf("None");
    return 0;
}

a题都能这难度就好了。

PAT A1050 String Subtraction (20 分)

#include<cstdio>
#include<cstring> 
bool hashtable[128]={false};
int main()
{
    char str1[10010],str2[10010];
    gets[str1];
    gets[str2];
    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]]==false)printf("%c",a[i]);
    }
}

循环输出

PAT B1005 继续(3n+1)猜想 (25 分)

#include <cstdio>
#include <algorithm>
using namespace std;
bool cmp(int a, int b)
{
    return a > b; //从小到大排列
}
int main()
{
    int n, m, a[110];
    scanf("%d", &n);
    bool hashtable[10000] = {0}; //hashtable[x]==true表示x被覆盖
    for (int i = 0; i < n; i++)
    {
        scanf("%d", &a[i]);
        m = a[i];
        while (m != 1)
        {
            //对m进行3n+1猜想操作
            if (m % 2 == 1)
                m = (3 * m + 1) / 2;
            else
                m = m / 2;
            hashtable[m]=true;      //被覆盖的数的flag设置为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;
}

PAT A1048 Find Coins (25 分)

#include<cstdio>
#include<algorithm>
using namespace std;
const int N = 1005;
int HashTable[N];
int main()
{
	int n, m, a;
	scanf("%d %d", &n, &m);
	for (int i = 0; i < n; i++)
	{
		scanf("%d", &a);
		++HashTable[a];
	}
	for (int i = 1; i < m; i++)
	{
		if (HashTable[i]>=1 && HashTable[m - i]>=1) {
			if (i == m - i && HashTable[i] <= 1) {
				continue;
			}
			printf("%d %d\n", i, m - i);
			return 0;
		}
	}
	printf("No Solution\n");
	return 0;
}
发布了24 篇原创文章 · 获赞 6 · 访问量 471

猜你喜欢

转载自blog.csdn.net/qq_39965800/article/details/90675929
4.2