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~