pat甲考前准备(pat-1152,1153,1154,1155)

最近准备考pat甲级,今天先找了去年的题目练了练。

总结:

(1)时间分配的不够合理,这次我用了15min读完了所有题,感觉不难就依次去做了,后来第二题卡了太久了,

就导致后面两题的时间不够了,最后两题没拿满分(后来补题时发现好简单QAQ),下次如果25分的题时间超过40min就应该

先看后面的。

(2)做题速度还是很慢,有时候思路都是有的,却要磨蹭好久,一定要改掉这个坏习惯。

 

pat-1152(hash)

思路:

用hash处理整个字符串,然后依次访问[i,i+k-1]区间的数字,判断是否为素数即可。

注意:

(1)hash数组是unsigned int类型的,不要写成 unsigned long long类型的,不然素数一判断就爆。

(2)从进行hash时要从[0,L-K]区间,考虑第一字母。

 

pat-1153(排序模拟)

题意:

三种要求输出

1、输出一个区块的所有排好序的卡号和成绩,卡号升序,成绩降序;

2、输出所有考场的考试人数,和这个考场内的考生成绩总和;

3、输出某一天的考场和考场内的考试人数,考场序号升序,人数降序。

思路:

排序,按照要求排序,还有stl的使用。

注意:

(1)这道题我WA了好久,开始我想直接全部排序完再直接输出,不然会超时,但是后来发现条件1,2容易满足,

条件3不容易,看列别人的文章,我发现可以现用现排(不管超不超时,先模拟出来再说)。

(2)三个条件都要考虑不存在的条件,一开始我第一就忘记考虑了。

(3)注意输出的格式,日期要是06d,6个单位。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
const int maxn = 100100;
struct Node{
	int score,date,sit_id,id,level;
	char ss[50];
}cur[maxn];
int sit_n[maxn],sit_s[maxn],vis[maxn];
struct NN{
	int id,num;
};
vector <NN> vc;
bool tmp(NN a,NN b)
{
	if(a.num!=b.num) return a.num>b.num;
	else return a.id<b.id;
}
bool cmp(Node a,Node b)
{
	if(a.level!=b.level) return a.level>b.level;
	else{
		if(a.score!=b.score) return a.score>b.score;
		else{
			if(strcmp(a.ss,b.ss)!=0) return strcmp(a.ss,b.ss)<0;
		}
	}
}
int MIN(int x,int y)
{
	return x<y?x:y; 
}
int main(void)
{
	int n,m,i,j,x,y,tp,ty;
	char str[50];
	scanf("%d %d",&n,&m);
	for(i=1;i<=n;i++){
		scanf("%s %d",str,&x);
		
		cur[i].score=x;
		
		if(str[0]=='T') cur[i].level=1;
		else if(str[0]=='A') cur[i].level=2;
		else if(str[0]=='B') cur[i].level=3;
		
		for(cur[i].sit_id=0,j=1;j<=3;j++) cur[i].sit_id=cur[i].sit_id*10+(str[j]-'0');
		
		for(cur[i].date=0,j=4;j<=9;j++) cur[i].date=cur[i].date*10+(str[j]-'0');
		
		for(cur[i].id=0,j=10;j<=12;j++) cur[i].id=cur[i].id*10+(str[j]-'0');
		
		sit_n[cur[i].sit_id]++;sit_s[cur[i].sit_id]+=cur[i].score;
		strcpy(cur[i].ss,str);
	}
	sort(cur+1,cur+1+n,cmp);
	int TT=n+1,AA=n+1,BB=n+1;
	for(i=1;i<=n;i++){
		if(cur[i].level==1) TT=MIN(TT,i);
		else if(cur[i].level==2) AA=MIN(AA,i);
		else if(cur[i].level==3) BB=MIN(BB,i);
	}
	for(j=1;j<=m;j++){
		scanf("%d",&ty);
		printf("Case %d: %d ",j,ty);
		if(ty==1){
			scanf("%s",str);
			printf("%s\n",str);
			if(str[0]=='T'){
				if(TT!=n+1)
				for(i=TT;cur[i].level==1;i++) printf("%s %d\n",cur[i].ss,cur[i].score);
				else printf("NA\n");
			}
			else if(str[0]=='A'){
				if(AA!=n+1)
				for(i=AA;cur[i].level==2;i++) printf("%s %d\n",cur[i].ss,cur[i].score);
				else printf("NA\n");
			}
			else if(str[0]=='B'){
				if(BB!=n+1)
				for(i=BB;cur[i].level==3;i++) printf("%s %d\n",cur[i].ss,cur[i].score);
				else printf("NA\n");
			}
			else printf("NA\n");
		}
		else if(ty==2){
			scanf("%d",&x);
			printf("%d\n",x);
			if(sit_n[x]!=0) printf("%d %d\n",sit_n[x],sit_s[x]);
			else printf("NA\n");
		}
		else{
			scanf("%d",&x);
			printf("%06d\n",x);
			memset(vis,0,sizeof(vis));
			vc.clear();
			NN opp;
			int ft=0;
			for(i=1;i<=n;i++)
			if(cur[i].date==x) vis[cur[i].sit_id]++,ft=1;
			/*if(ft=0){
				printf("NA\n");
				continue;
			}*/
			for(i=1;i<=n;i++)
			if(vis[cur[i].sit_id]!=0){
				opp.id=cur[i].sit_id;
				opp.num=vis[cur[i].sit_id];
				vc.push_back(opp);
				vis[cur[i].sit_id]=0;
			}
			
			if(vc.size()!=0){
				sort(vc.begin(),vc.end(),tmp);
				for(i=0;i<vc.size();i++) printf("%03d %d\n",vc[i].id,vc[i].num);
			}
			else printf("NA\n");
		}
	}
	
	return 0;
}

 

 

pat-1154(送分题)

思路:就是判断一下一条边的两个点颜色是否相同。

 

pat-1155(二叉树的遍历+堆)

思路:

二叉堆就是一个完全二叉树,可以用中序遍历判断是最大堆还是最小堆,

完全二叉树性质:最多2^x-1个节点,最少2^(x-1)-1个节点,所以求出最少的节点个数m,

所以m就是最右边的节点,然后依次从叶子节点比遍历就好了。

(感觉25和30分的题目出反了)。

#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
const int maxn = 100100;
int tree[maxn],f1,f2,vis[maxn];
vector <int> vc[maxn];
void In1(int x)
{
	if(tree[x]){
		In1(x*2);
		if(tree[x*2]&&tree[x*2]<tree[x]) f1=0;
		if(tree[x*2+1]&&tree[x*2+1]<tree[x]) f1=0;
		if(tree[x*2]+tree[x*2+1]==0) vis[x]=1;
		In1(x*2+1); 
	}
}
void In2(int x)
{
	if(tree[x]){
		In2(x*2);
		if(tree[x*2]&&tree[x*2]>tree[x]) f2=0;
		if(tree[x*2+1]&&tree[x*2+1]>tree[x]) f2=0;
		if(tree[x*2]+tree[x*2+1]==0) vis[x]=1;
		In2(x*2+1);
	}
}
int main(void)
{
	int n,i,j,m=1,N=2;
	scanf("%d",&n);
	for(i=1;i<=n;i++) scanf("%d",&tree[i]);
	while(N<=n){
		N*=2;m*=2;
	}
	f1=f2=1;
	In1(1);In2(1);
	for(i=1;i<=n;i++)
	if(vis[i]==1){
		for(j=i;j>0;j/=2) vc[i].push_back(tree[j]);
	}
	m--;
	for(i=m;i>=1;i--)
	if(vis[i]==1){
		int tp=vc[i].size();
		for(j=tp-1;j>=0;j--){
			if(j!=tp-1) printf(" ");
			printf("%d",vc[i][j]);
		}
		printf("\n");
	}
	for(i=n;i>=m+1;i--)
	if(vis[i]==1){
		int tp=vc[i].size();
		for(j=tp-1;j>=0;j--){
			if(j!=tp-1) printf(" ");
			printf("%d",vc[i][j]);
		}
		printf("\n");
	}
	if(f1) printf("Min Heap\n");
	else if(f2) printf("Max Heap\n");
	else printf("Not Heap\n");
	return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值