PTA甲级模拟第八弹:1164-1167

本文总结了PAT在线测评1140-1167题目的特点,指出题目难度适中,适合打基础,但知识点覆盖不全,需广泛练习。详细解析了四道题目,包括字符串处理、链表操作、图论基础和二叉树应用,并提供了AC代码。建议通过PAT进行基础训练,同时拓宽知识面以应对更广泛的机试题目。
摘要由CSDN通过智能技术生成

1. 知识点总结

最后一弹🤣,开个玩笑啊咧(前面还有好多债😅)

目前1140-1167给我的感觉是——整体没有特别难的(这里指的是难度≥🐸🐸🐸的题目,当然菜还是菜得依旧😐,回家效率真的……昂一言难尽),而且随着题号的增加,套路题感觉没有变化,模板该背还是得背,最好是能够灵活运用,因为一般四道题目有一道考察的是应变(俗称“卡分题”)

感觉pta可以打基础~但是涉及的知识点还是不全,准备机试还是得练比较广……不然就是白给😓

题号难度知识点
1164🐸字符串处理+矩阵
1165🐸😅链表
1166🐸图的简单应用
1167🐸中序+堆(二叉树简单应用)

2.分题题解

2.1 第一题1164 Good in C (20 分)

【题目传送门】

字符串处理与矩阵的基本使用,注意心态稳住~

  • 格式严格按照题目意思(不可以毛躁)

  • 难点在于句子的切分,涉及到string子串函数使用

#include<bits/stdc++.h>
using namespace std;
string sentence;
vector<string>words;//切分句子 
struct Alpha{
	char matrix[7][5];
}; 
Alpha alpha[26];
void Cut(){
	//切分句子
	int len=sentence.length();
	int left=0,right=0;
	string word;
	bool flag=false;
	int i;
	for(i=0;i<len;i++){
		if(sentence[i]<='Z'&&sentence[i]>='A'){
			if(!flag){
				flag=true;
				left=i;
			}
		}else{
			//前面出现的是连续的字母 
			if(flag){
				word=sentence.substr(left,i-left);
				words.push_back(word);
				flag=false;
			} 
		}
	}
	if(flag&&i-left>0){
		word=sentence.substr(left,i-left);
		words.push_back(word);
	} 
}
void Print(string word){
	int len=word.length();
	for(int row=0;row<7;row++){
		if(row){
			printf("\n");
		}
		for(int col=0;col<len;col++){
			//打印每一个字母
			if(col!=0)printf(" ");
			for(int i=0;i<5;i++){
				int id;
				if(word[col]<='Z'&&word[col]>='A'){
					id=word[col]-'A';
				}else{
					id=word[col]-'a';
				}
				printf("%c",alpha[id].matrix[row][i]);
			} 
		}
		
	}
}
int main(){
	for(int i=0;i<26;i++){
		for(int row=0;row<7;row++){
			for(int column=0;column<5;column++){
				cin>>alpha[i].matrix[row][column];
			}
		}
	}
	getchar();
	getline(cin,sentence);
	Cut(); 
	for(int i=0;i<words.size();i++){
		if(i)printf("\n\n");
		Print(words[i]);
	}
	return 0;
}

2.2 第二题1165 Block Reversing (25 分)

【题目链接】

静态列表基础题,不是很难,注意输出的细节

但是需要订正😓

第一版:24/25

#include<bits/stdc++.h>
using namespace std;
int L,N,num;
int head;
struct Node{
	int val;
	int addr;
	int next;
};
map<int,Node>nodes;
int addr,val,next_node;
vector<Node>list1;
int main(){
	scanf("%d%d%d",&head,&N,&L);
	for(int i=0;i<N;i++){
		scanf("%d%d%d",&addr,&val,&next_node);
		Node temp;
		temp.addr=addr;
		temp.val=val;
		temp.next=next_node;
		nodes[addr]=temp;
	}
	//首先
	int p=head;
	while(p!=-1){
		list1.push_back(nodes[p]);
		p=nodes[p].next;
	} 
	//list1中存放 :如何输出
	//0 1 2   3 4 5  6 7
	int n=N/L+(N%L==0?0:1);
	int res=N%L; 
	int fid;
	bool flag=false;
	for(int i=n;i>=1;i--){
		if(res){
			num=res;
			fid=(i-1)*L;
		}else{
			num=L;
			fid=(i-1)*L;
		}
		if(res)res=0;
		for(int j=fid;j<fid+num;j++){
			if(!flag){
				flag=true;
			}else{
				printf(" %05d\n",list1[j].addr);
			}
			printf("%05d %d",list1[j].addr,list1[j].val);
		}
	}
	printf(" -1");
	return 0;
}

第二版:AC

#include<bits/stdc++.h>
using namespace std;
int head,n,block;
int arr,val,nex;
struct Node{
	int arr;
	int val;
	int next;
};
map<int,Node>nodes;
vector<Node>list0;
int main(){
	scanf("%d%d%d",&head,&n,&block);
	for(int i=0;i<n;i++){
		scanf("%d%d%d",&arr,&val,&nex);
		Node temp;
		temp.arr=arr;
		temp.val=val;
		temp.next=nex;
		nodes[arr]=temp;
	}
	int p=head;
	while(p!=-1){
		list0.push_back(nodes[p]);
		p=nodes[p].next;
	}
	//改变,输出: 0 1 2   3 4 5   6 7 
	//1 2 3 4    5 6 7 8
	bool flag=false;
	int len=list0.size();
	int res=len%block;
	int times=len/block;
	if(res!=0)times++;
	//printf("需要%d次\n",times);
	for(int i=1;i<=times;i++){
		int first=(times-i)*block;
		//printf("first=%d\n",first);
		int num=block;
		if(i==1&&res)num=res;
		//printf("num=%d\n",num); 
		//输出 
		for(int j=0;j<num;j++){
			if(!flag){
				flag=true;
			}else{
				printf(" %05d\n",list0[first+j].arr);
			}
			printf("%05d %d",list0[first+j].arr,list0[first+j].val);
		}
	}
	printf(" -1"); 
	return 0;
}


/*一个测试点:
00100 8 4
71120 7 88666
00000 4 99999
00100 1 12309
68237 6 71120
33218 3 00000
99999 5 68237
88666 8 -1
12309 2 33218
需要2次
00100 1 12309
12309 2 33218
33218 3 00000
00000 4 -1

*/ 

2.3 第三题 1166 Summit (25 分)

【题目链接】

图论基础题:

🤣邻接图,不卡时间和内存,放心写

#include<bits/stdc++.h>
using namespace std;
int n,m;
int k,l;
int a ,b;
vector< vector<int> >relation;
vector<int>q;
vector<int>visnum;
vector<bool>isin;
int main(){
	scanf("%d%d",&n,&m);
	relation.resize(n+1);
	visnum.resize(n+1);
	isin.resize(n+1);
	for(int i=0;i<m;i++){
		scanf("%d%d",&a,&b);
		if(a==b)continue;
		relation[a].push_back(b);
		relation[b].push_back(a);	
	}
	scanf("%d",&k);
	for(int cnt=1;cnt<=k;cnt++){
		fill(visnum.begin(),visnum.end(),0);
		fill(isin.begin(),isin.end(),false);
		scanf("%d",&l);
		q.resize(l);
		for(int i=0;i<l;i++){
			scanf("%d",&q[i]);
			isin[q[i]]=true;
		}
		for(int i=0;i<l;i++){
			int id=q[i];
			for(int j=0;j<relation[id].size();j++){
				int fid=relation[id][j];
				visnum[fid]++;
			}
		}
		//计算 1 不合法 2 有人忘记邀请 
		int flag=0; 
		int ans=n+1; 
		for(int id=1;id<=n;id++){
			if(isin[id]&&visnum[id]!=l-1){
				flag=1;
				printf("Area %d needs help.\n",cnt);
				break;
			}else if(!isin[id]&&visnum[id]==l){
				ans=min(ans,id);
				flag=2;
			}
		} 
		if(flag==2){
			printf("Area %d may invite more people, such as %d.\n",cnt,ans);
		} else if(flag==0){
			printf("Area %d is OK.\n",cnt);
		}	
	}
	return 0;
}

2.4 第四题 1167 Cartesian Tree (30 分)

【题目链接】

简单题,属于是中序+堆排序重建树结构的一类题(类似中序+后序||中序+先序),难度要简单一点,每次从中序序列(inL,inR)之间找到最小的作为根节点,左右序列分别递归为下一次的左右子树

#include<bits/stdc++.h>
using namespace std;
int N;
const int INF=99999999;
//小顶堆中序遍历输出的结果---->层序遍历输出结果
struct Node{
	int val;
	Node*left=NULL;
	Node*right=NULL;
}; 
vector<int>in;
Node*build(int inL,int inR){
	if(inR<inL){
		return NULL;
	}
	//找到根节点
	int min_num=INF;
	int min_id=-1;
	for(int k=inL;k<=inR;k++){
		if(in[k]<min_num){
			min_num=in[k];
			min_id=k;
		}
	}
	Node *root=new Node;
	root->val=min_num;
	root->left=build(inL,min_id-1);
	root->right=build(min_id+1,inR);
	return root;
}
//层次遍历
void levelTravel(Node *root){
	queue<Node*>q;
	q.push(root);
	bool flag=false;
	while(!q.empty()){
		Node*top=q.front();
		Node*temp;
		q.pop();
		if(top->left!=NULL){
			temp=top->left;
			q.push(temp);
		}
		if(top->right!=NULL){
			temp=top->right;
			q.push(temp);
		}
		if(!flag){
			flag=true;
		}else{
			printf(" ");
		}
		printf("%d",top->val);
	}
	return;
}

int main(){
	scanf("%d",&N);	
	in.resize(N);
	for(int i=0;i<N;i++){
		scanf("%d",&in[i]);
	}
	Node *root=build(0,N-1);
	levelTravel(root);
	return 0;
}

碎碎念,这年的考题比较easy~

3. 参考链接

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值