目录
PAT A1084 Broken Keyboard (20 分)
PAT A1092 To Buy or Not to Buy (20 分)
PAT A1050 String Subtraction (20 分)
学习散列舒服多了,难度比排序低太多,也算是长自信的一个环节吧..
主要的套路方法比较单一,就不列举花里胡哨的方法了,只列举主要要用的方法和实际程序。
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;
}