【PAT】攀拓(PAT)- 程序设计(甲级)2023年夏季考试自测

个人学习记录,代码难免不尽人意。

今天又斥资巨款买了PAT甲级2023年夏季的考试真题做了做,得分
95,还买了时光机,在当时排名42名。总的来说还是比较满意的!有些地方当时做的时候卡住了但是后面回过头来重新想的时候还是做出来不少的。

所以说,以后做题无论是真题还是自测题,都要给每道题限定好时间,不要硬耗在一道题上。

下面是我四道题的解法和思路,最后一道题没有满分但是已经找出了问题所在。
A-1 Trap

A robot is designed to move on a map from South toward North. When some obstacle is encountered, the robot can only turn toward West and moves until it can turn toward North and continue.

Given a squared map with n×n blocks, a robot can start from any position below the bottom line (South) and its target is to reach the top line (North). (By the way, kindly remind you that the left-hand-side of the map is West and the right-hand-side is East.)

If some obstacles are placed in the map, the robot might get trapped if it starts from certain positions and can never reach the North line. For example, in the situation given by the following figure, the robot will be trapped if it starts from either position 7 or 8.
【PAT】攀拓(PAT)- 程序设计(甲级)2023年夏季考试自测_第1张图片
Your job is to point out those starting positions which will get the robot trapped.

Note: it is assumed that a robot can move out of the map boundary, and all the blocks around the map are open, without any obstacle. Hence if the robot starts from any position out of the West or East boundary, it can certainly reach North without any problem. Therefore we only have to consider the positions between the West and East boundaries (e.g. the positions from 1 to 10 below the South line in the above figure). Besides, as long as the robot can reach the North line, it is considered successful even of it ends up at out of the boundary (e.g. the robot will have to move out of the map if starts from either the positions 1 or 2, but it can still reach the North line).

Input Specification:
Each input file contains one test case. Each case starts from a positive integer n (≤100) in a line, which is the size of the map. Then n lines follow, each contains n characters, which are either 0 for an open block, or 1 for a block with obstacle. The first line corresponds to the North boundary and the last line the South.

Output Specification:
Output in a line all the starting positions which can get the robot trapped, in increasing order. The positions are indexed from West to East, starting from 1. It is guaranteed that there is at least one output.
All the numbers must be separated by 1 space, and there must be no extra space at the beginning or the end of the line.

Sample Input:
10
0000000000
0000111010
1100100011
0000110001
0000000011
0000000000
0100000100
0001000000
0001000000
0001100000
Sample Output:
7 8

#include 
#include
#include
using namespace std;
const int maxn=110;
int G[maxn][maxn];

int main() {
	
	int n;
	scanf("%d",&n);
	getchar();
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			char a;
			scanf("%c",&a);
			G[i][j]=a-'0';
		}
		getchar();
	}
    //下面还有一层,汗
	for(int i=1;i<=n;i++){
		G[n+1][i]=0;
	} 
	n+=1;
	vector<int> v;
    for(int p=1;p<=n;p++){

    	int i=p;
    	int j=n;
    	bool flag=true;
    	while(j>=1){
//    		if(p==7){
//    			cout << j<
//    			cout << i<
//			}
    		while(j>=1&&G[j][i]!=1){
    		j--;
		     }
		    if(j==0) break;
		    else{
		    	if(G[j][i]==1){
		    	j+=1;
			}
				int m=i-1;
		    	for(m;m>0;m--){
		    		if(G[j][m]!=1){
		    			i=m;
		    			break;
					}
					if(G[j][m]==1&&G[j-1][m+1]==1){
		
						flag=false;
						break;
					}
				}
				if(m==0){
					break;
				}
			
			if(!flag){
				v.push_back(p);
				break;
			}			
		}
			} 	    
		    
	}
	for(int i=0;i<v.size();i++){
		printf("%d",v[i]);
		if(i!=v.size()-1) printf(" ");
		else printf("\n");
	}
}

这道题一开始没审清楚题意唉,一开始我没注意到最下面还有一行!。我以为是从标号为10的那一行开始的。现在想想当时我的想法有点笨笨:第四个位置,我一开始以为(10,4)这个位置是黑块,就直接一路向左了,但题意的要求是(10,4)如果是黑块,那么向右查看一位,如果能向上,那么就一直向上,所以说,4,5等同于3!!
明白了这个,这道题也就不难了。

A-2 Queue Using Two Stacks
A queue (FIFO structure) can be implemented by two stacks (LIFO structure) in the following way:
【PAT】攀拓(PAT)- 程序设计(甲级)2023年夏季考试自测_第2张图片

Assume that each operation of push or pop takes 1 unit of time. You job is to tell the time taken for each dequeue.

Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤10 3), which are the number of operations. Then N lines follow, each gives an operation in the format

Operation Element
where Operation being I represents enqueue and O represents dequeue. For each I, Element is a positive integer that is no more than 10
6
. No Element is given for O operations.
It is guaranteed that there is at least one O operation.

Output Specification:
For each dequeue operation, print in a line the dequeued element and the unites of time taken to do this dequeue. The numbers in a line must be separated by 1 space, and there must be no extra space at the beginning or the end of the line.
In case that the queue is empty when dequeue is called, output in a line ERROR instead.

Sample Input:
10
I 20
I 32
O
I 11
O
O
O
I 100
I 66
O
Sample Output:
20 5
32 1
11 3
ERROR
100 5

#include 
#include
#include
#include
#include
using namespace std;
const int maxn=1010;

stack<int> a,b;
string str[maxn]; 
int cal=0;
string tostring(int n){
	string a;
	while(n!=0){
		int b=n%10;
		n=n/10;
		char temp=b+'0';
		a=temp+a;
	}
	return a;
}
int main() {
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		string s;
		cin >> s;
		if(s[0]=='I'){
			int num;
			scanf("%d",&num);
			a.push(num);
		}
		else{
			int cnt=0;
			if(b.empty()){
				if(a.empty()){
					str[cal++]="ERROR";
					continue;
				}
				else{
					while(!a.empty()){
						cnt++;
						int number=a.top();
						a.pop();
						b.push(number);
						cnt++;
					}
					int temp=b.top(); 
					b.pop();
					cnt++; 
					string kong=" ";
					str[cal++]=tostring(temp)+kong+tostring(cnt);
					
				}
				
			}
			else{
				int temp=b.top();
				b.pop();
				cnt++;
				string kong=" ";
				str[cal++]=tostring(temp)+kong+tostring(cnt);
			}
		}
	}
	for(int i=0;i<cal;i++){
		cout << str[i];
		if(i!=cal-1) cout << endl;
		
	}
}

这道题没什么好说的,就是栈的应用,难度很小。

A-3 Rank of Binary Tree
【PAT】攀拓(PAT)- 程序设计(甲级)2023年夏季考试自测_第3张图片
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (≤20), which is the total number of nodes in the tree. Then given in the following 2 lines are the inorder and preorder traversal sequences of the tree, respectively. All the keys in the tree are distinct positive integers in the range of int.

Output Specification:
For each case, print in a line the way we calculate the rank, and the integer part of the rank. The format is:

n1 * n2 / n0 = rank
Sample Input:
9
2 3 1 5 4 7 8 6 9
1 2 3 6 7 4 5 8 9
Sample Output:
2 * 3 / 4 = 1

#include 
#include
#include
#include
#include
using namespace std;
const int maxn=25;
int in[maxn];
int pre[maxn];
struct node{
	int data;
	node* lchild;
	node* rchild;
};
node* newnode(int data){
	node* root=new node;
	root->data=data;
	root->lchild=NULL;
	root->rchild=NULL;
	return root;
}
node* create(int prel,int prer,int inl,int inr){
     if(prel>prer) return NULL;
     int mid=pre[prel];
     node* root=newnode(mid);
     int index;
     for(int i=inl;i<=inr;i++){
     	if(in[i]==mid){
     		index=i;
     		break;
		 }
	 }
	 int leftnum=index-inl;
	 root->lchild=create(prel+1,prel+leftnum,inl,index-1);
	 root->rchild=create(prel+leftnum+1,prer,index+1,inr);
	 return root;
}
int n0=0,n1=0,n2=0;
void bfs(node* root){
	queue<node* > q;
	q.push(root);
	while(!q.empty()){
		int cnt=0;
		node* now=q.front();
		q.pop();
		if(now->lchild!=NULL){
			cnt++;
			q.push(now->lchild); 
		}
		if(now->rchild!=NULL){
			cnt++;
			q.push(now->rchild); 
		}
		if(cnt==2) n2+=1;
		else if(cnt==1) n1+=1;
		else n0+=1;
	}
}
int main() {
       int n;
       scanf("%d",&n);
       for(int i=0;i<n;i++){
       	scanf("%d",&in[i]);
	   }
	   for(int i=0;i<n;i++){
       	scanf("%d",&pre[i]);
	   }
	   node* root=create(0,n-1,0,n-1);
	   bfs(root);
	   int res=n1*n2/n0;
	   printf("%d * %d / %d = %d\n",n1,n2,n0,res);
}

这道题也非常简单,没什么好说的。

A-4 Big Number
How to generate a big number of N digits randomly? One way is to find N kids, give each one a card with one’s index written on one side (hence it is assumed that the kids are indexed from 1 to N), and ask them to write down a 1-digit number randomly on the other side. Then let the kids pin their digits in a line, on the wall, one by one in ascending order of their indices.

However, it’s very difficult to let hundreds of thousands of kids to follow the order. The result is that we have cards pinned randomly all over the wall, some even show the wrong sides. For example, if the 23rd kid has written down 8, we are supposed to find the number 8 on the wall. But instead we might find 23… Your job is to rearrange these cards so that we can obtain the big number as required.

Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤10
5
). Then N lines follow, each describes a card in the format n1 n2 where the two numbers are the numbers written on the two sides of a card.

Output Specification:
For each test case, print in a line the N-digit number as required. That is, print the digits written by the kids in ascending order of their indices. In case that there are 1-digit numbers written on both sides, it would be hard to tell which one is the index and which one is the number written by the kid. Hence the solution may not be unique. In this case, just output the smallest resulting number.

It is guaranteed that a solution exists.

Sample Input:
12
7 11
8 9
3 1
2 12
4 6
10 0
5 1
2 5
6 8
1 4
7 2
9 3
Sample Output:
359114268072

25分代码

#include 
#include
#include
#include
#include
#include
using namespace std;
const int maxn=100100;//写成10010了最后一个测试点错误 
vector<pair<int,int> > temp,table[maxn];
int hashtable[maxn]={0};
int main() {
     int n;
     scanf("%d",&n);
     for(int i=0;i<n;i++){
     	int a,b;
     	scanf("%d %d",&a,&b);
     		hashtable[a]++;
     	hashtable[b]++;
     	temp.push_back(make_pair(a,b));
     	
	 }
	 for(int i=0;i<n;i++){ 
	    int a,b;
	 	a=temp[i].first;b=temp[i].second;
	 	if(hashtable[a]==1){
		  hashtable[b]--;
		 }
		if(hashtable[b]==1){
			hashtable[a]--;
		}
		if(a==b)
		hashtable[a]--;
	 }
	 for(int i=0;i<n;i++){
	 	int a,b;
	 	a=temp[i].first;b=temp[i].second;
	 	if(a==0){
	 	table[b].push_back(make_pair(b,a));
		 }
		else if(b==0){
			table[a].push_back(make_pair(a,b));
		}
	 	else if(hashtable[a]==1){
	 		table[a].push_back(make_pair(a,b));
		 }

		else if(hashtable[b]==1){
			table[b].push_back(make_pair(b,a));
		}
	 	else if(a>=10){
     		table[a].push_back(make_pair(a,b));
		 } 
		else if(a<b){
				table[a].push_back(make_pair(a,b));
		}
     	else if(b>=10){
     		table[b].push_back(make_pair(b,a));
		 }
		else if(a>=b){
			table[b].push_back(make_pair(b,a));
		}
	 }
	 for(int i=1;i<=n;i++){
	 	
	 int min=table[i][0].second;
	 int index=0;
	 	for(int j=0;j<table[i].size();j++){
		     if(min>table[i][j].second){
		     	min=table[i][j].second;
		     	index=j;
			 }
		     
		 }
		for(int j=0;j<table[i].size();j++){
			if(j!=index){
				table[table[i][j].second].push_back(make_pair(table[i][j].second,table[i][j].first));
			}
		}
		printf("%d",min);
	 }
	 printf("\n");
}

很麻烦且复杂的一道题!如果一开始数据结构用错了那么基本不可能满分做出来了,因为牵扯的逻辑太复杂很容易漏下或者改错一些地方。
我的做法**漏下了一种情况,那就是如果有两种一样的卡片该如何处理,那肯定是对换。**我没有用map,导致了不好处理,所以这是一个大问题。
推荐下面这位博主的做法:
PAT甲级2023夏季考试题解(A-1 Trap,A-2 Queue Using Two Stacks,A-3 Rank of Binary Tree,A-4 Big Number)

你可能感兴趣的:(PTA,c++,pat,算法,数据结构)